Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opencv 如何使用Open CV读取模拟仪表_Opencv_Raspberry Pi_Detect - Fatal编程技术网

Opencv 如何使用Open CV读取模拟仪表

Opencv 如何使用Open CV读取模拟仪表,opencv,raspberry-pi,detect,Opencv,Raspberry Pi,Detect,我对尝试使用树莓圆周率和开放式CV读取模拟量表感兴趣。我只在opencv中真正搞砸了人脸检测,所以我甚至不知道从哪里开始。有什么想法,起点吗?您可以使用HoughCircles方法检测圆,并使用Python中opencv库的HoughLinesP方法检测线。在检测到这些之后,您可以通过三角法从测线位置找出量规的值。 您可以看到python中的示例代码。它基本上是这样做的: 用imread方法读取图像 用cvtColor将其变成灰色 用HoughCircles找出圆的中心x、y坐标和半径,这些方

我对尝试使用树莓圆周率和开放式CV读取模拟量表感兴趣。我只在opencv中真正搞砸了人脸检测,所以我甚至不知道从哪里开始。有什么想法,起点吗?

您可以使用HoughCircles方法检测圆,并使用Python中opencv库的HoughLinesP方法检测线。在检测到这些之后,您可以通过三角法从测线位置找出量规的值。 您可以看到python中的示例代码。它基本上是这样做的:

  • 用imread方法读取图像
  • 用cvtColor将其变成灰色
  • 用HoughCircles找出圆的中心x、y坐标和半径,这些方法有一些参数可以调整
  • 再次使用HoughLinesP方法检测线。应调整参数
  • 计算该值,考虑量规上的最大值、最小值和量规的角度间隔
参考: 希望这有帮助。 代码:

导入操作系统
进口cv2
进口numpy
def getScriptDir():
currentFile=uuuu file_u35;可以是“我的脚本”或“/myu脚本”或
realPath=os.path.realPath(当前文件)#/home/user/test/my_script.py
dirPath=os.path.dirname(realPath)
返回路径
def getUserRealGaugeDetails():
最小角度=输入(“最小角度:”)#可能的最小角度
最大角度=输入(“最大角度”)#最大可能角度
最小值=输入(“最小值:”)#通常为零
最大值=输入('max deger:')#仪表的最大读数
单位=输入('Birim girin:')
返回最小角度、最大角度、最小值、最大值、单位
def SETSTATICUSERREALGAGEDETAILS():
最小角度=5#输入(“最小角度(刻度盘的最小可能角度)-以度为单位:”)#最小可能角度
最大角度=355#输入(“最大角度(最大可能角度)-以度为单位:”)#最大可能角度
最小值=-20#输入(“最小值:”)#通常为零
最大值=120#输入(“最大值”)#仪表的最大读数
单位='b'#输入('输入单位:')
返回最小角度、最大角度、最小值、最大值、单位
def getImage():
dirPath=getScriptDir()
dirPath+=“/images/1.jpg”
返回cv2.imread(dirPath)
def距离2点(x1、y1、x2、y2):
#打印np.sqrt((x2-x1)^2+(y2-y1)^2)
返回numpy.sqrt((x2-x1)**2+(y2-y1)**2)
def平均圆(圆,b):
平均值x=0
平均值y=0
平均值=0
对于范围(b)中的i:
#可选-多个圆的平均值(当仪表处于微小角度时可能发生)
平均值=平均值+圆圈[0][i][0]
平均值=平均值+圆[0][i][1]
平均值=平均值+圆圈[0][i][2]
平均x=int(平均x/(b))
平均值y=int(平均值y/(b))
平均r=int(平均r/(b))
返回平均值x,平均值y,平均值r
#返回圆的圆心和半径
def getCircleAndCustomize(图像):
高度,宽度=图像。形状[:2]
gray=cv2.CVT颜色(图像,cv2.COLOR_BGR2GRAY)#转换为灰色
#灰色=cv2.高斯模糊(灰色,(5,5,0)
#灰色=cv2.medianBlur(灰色,5)
#cv2.imwrite('C:/Users/okarademirci/Desktop/analog gauge reader/images/gauge-gray-2.jpg',灰色)
#检测圆
#将搜索限制在可能半径的35-48%范围内,可以在不同样本中获得相当好的结果。记得吗
#这些是对应于可能半径搜索范围的像素值。
圆=cv2.HoughCircles(灰色,cv2.HOUGH_渐变,1,20,numpy.数组([]),100,50,整数(高度*0.35),整数(高度*0.48))
#坐标和半径
a、 b,c=圆形
x、 y,r=平均圆(圆,b)
返回x,y,r
def get_当前_值(img、最小_角、最大_角、最小_值、最大_值、x、y、r):
gray2=cv2.CVT颜色(img,cv2.COLOR\u BGR2GRAY)
#设置阈值和最大值
thresh=175
最大值=255
#出于测试目的,发现cv2.THRESH_BINARY_INV性能最佳
#th,dst1=cv2.阈值(灰度2,阈值,最大值,cv2.阈值二进制);
#th,dst2=cv2.阈值(灰度2,阈值,最大值,cv2.阈值二进制INV);
#th,dst3=cv2.阈值(灰度2,阈值,最大值,cv2.阈值);
#th,dst4=cv2.阈值(灰度2,阈值,最大值,cv2.阈值为零);
#th,dst5=cv2.阈值(灰度2,阈值,最大值,cv2.阈值到零值);
#cv2.imwrite('仪表-%s-dst1.%s'(仪表号,文件类型),dst1)
#cv2.imwrite('仪表-%s-dst2.%s'(仪表号,文件类型),dst2)
#cv2.imwrite('仪表-%s-dst3.%s'(仪表号,文件类型),dst3)
#cv2.imwrite('仪表-%s-dst4.%s'(仪表号,文件类型),dst4)
#cv2.imwrite('仪表-%s-dst5.%s'(仪表号,文件类型),dst5)
#应用有助于查找线的阈值
th,dst2=cv2.阈值(灰度2,阈值,最大值,cv2.阈值二进制值)
#发现Hough线通常在不使用Canny/blurring的情况下表现更好,但也有一些例外,它只适用于Canny/blurring
#dst2=cv2.medianBlur(dst2,5)
#dst2=cv2.Canny(dst2,50,150)
#dst2=cv2.GaussianBlur(dst2,(5,5,0)
#对于测试,显示阈值化后的图像
dirPath=getScriptDir()+'/images/posterreshold.jpg'
cv2.imwrite(dirPath,dst2)
#找线
minLineLength=10
maxLineGap=0
lines=cv2.HoughLinesP(image=dst2,rho=3,theta=numpy.pi/180,threshold=100,minLineLength=minLineLength,maxLineGap=0)#rho设置为3以检测更多的线,更容易获取更多线,然后稍后过滤掉它们
#出于测试目的,显示所有找到的行
#对于范围(0,len(行))中的i:
#对于[i]行中的x1、y1、x2、y2:
#cv2.线(img,(x1,y1),(x2,y2),(0255,0),2)
#cv2.imwrite('gauge-%s-lines-test.%s'(gauge\u编号,文件类型),img)
#删除给定半径以外的所有线
最后一行列表=[]
#打印“半径:%s”%r
diff1LowerBound=0.15#diff1LowerBound和diff1UpperBound确定直线与中心的距离
diff1UpperBound=0.25
diff2LowerBoun
import os
import cv2
import numpy

def getScriptDir():
    currentFile = __file__  # May be 'my_script', or './my_script' or
    realPath = os.path.realpath(currentFile)  # /home/user/test/my_script.py
    dirPath = os.path.dirname(realPath)
    return dirPath
def getUserRealGaugeDetails():
    min_angle = input('Min derece: ') #the lowest possible angle
    max_angle = input('Max derece ') #highest possible angle
    min_value = input('Min deger: ') #usually zero
    max_value = input('Max deger: ') #maximum reading of the gauge
    units = input('Birim girin: ')
    return min_angle,max_angle,min_value,max_value,units

def setStaticUserRealGaugeDetails():
    min_angle = 5 # input('Min angle (lowest possible angle of dial) - in degrees: ') #the lowest possible angle
    max_angle = 355  # input('Max angle (highest possible angle) - in degrees: ') #highest possible angle
    min_value = -20 #input('Min value: ') #usually zero
    max_value = 120 #input('Max value: ') #maximum reading of the gauge
    units = 'b' #input('Enter units: ')
    return min_angle,max_angle,min_value,max_value,units

def getImage():
    dirPath = getScriptDir()
    dirPath += "/images/1.jpg"
    return cv2.imread(dirPath)
def distance2Points(x1, y1, x2, y2):
    #print np.sqrt((x2-x1)^2+(y2-y1)^2)
    return numpy.sqrt((x2 - x1)**2 + (y2 - y1)**2)

def averageCircle(circles, b):
    avg_x=0
    avg_y=0
    avg_r=0
    for i in range(b):
        #optional - average for multiple circles (can happen when a gauge is at a slight angle)
        avg_x = avg_x + circles[0][i][0]
        avg_y = avg_y + circles[0][i][1]
        avg_r = avg_r + circles[0][i][2]
    avg_x = int(avg_x/(b))
    avg_y = int(avg_y/(b))
    avg_r = int(avg_r/(b))
    return avg_x, avg_y, avg_r

#return the center and radius of the circle
def getCircleAndCustomize(image):
    height, width = image.shape[:2]
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  #convert to gray

    # gray = cv2.GaussianBlur(gray, (5, 5), 0)
    # gray = cv2.medianBlur(gray, 5)
    # cv2.imwrite('C:/Users/okarademirci/Desktop/analog-gauge-reader/images/gauge-gray-2.jpg', gray)
    #detect circles
    #restricting the search from 35-48% of the possible radii gives fairly good results across different samples.  Remember that
    #these are pixel values which correspond to the possible radii search range.
    circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 20, numpy.array([]), 100, 50, int(height*0.35), int(height*0.48))
    #coordinates and radius
    a, b, c = circles.shape
    x,y,r = averageCircle(circles, b)
    return x ,y ,r

def get_current_value(img, min_angle, max_angle, min_value, max_value, x, y, r):

    gray2 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # Set threshold and maxValue
    thresh = 175
    maxValue = 255

    # for testing purposes, found cv2.THRESH_BINARY_INV to perform the best
    # th, dst1 = cv2.threshold(gray2, thresh, maxValue, cv2.THRESH_BINARY);
    # th, dst2 = cv2.threshold(gray2, thresh, maxValue, cv2.THRESH_BINARY_INV);
    # th, dst3 = cv2.threshold(gray2, thresh, maxValue, cv2.THRESH_TRUNC);
    # th, dst4 = cv2.threshold(gray2, thresh, maxValue, cv2.THRESH_TOZERO);
    # th, dst5 = cv2.threshold(gray2, thresh, maxValue, cv2.THRESH_TOZERO_INV);
    # cv2.imwrite('gauge-%s-dst1.%s' % (gauge_number, file_type), dst1)
    # cv2.imwrite('gauge-%s-dst2.%s' % (gauge_number, file_type), dst2)
    # cv2.imwrite('gauge-%s-dst3.%s' % (gauge_number, file_type), dst3)
    # cv2.imwrite('gauge-%s-dst4.%s' % (gauge_number, file_type), dst4)
    # cv2.imwrite('gauge-%s-dst5.%s' % (gauge_number, file_type), dst5)

    # apply thresholding which helps for finding lines
    th, dst2 = cv2.threshold(gray2, thresh, maxValue, cv2.THRESH_BINARY_INV)

    # found Hough Lines generally performs better without Canny / blurring, though there were a couple exceptions where it would only work with Canny / blurring
    #dst2 = cv2.medianBlur(dst2, 5)
    #dst2 = cv2.Canny(dst2, 50, 150)
    #dst2 = cv2.GaussianBlur(dst2, (5, 5), 0)

    # for testing, show image after thresholding
    dirPath = getScriptDir() + '/images/afterTreshold.jpg'
    cv2.imwrite(dirPath, dst2)

    # find lines
    minLineLength = 10
    maxLineGap = 0
    lines = cv2.HoughLinesP(image=dst2, rho=3, theta=numpy.pi / 180, threshold=100,minLineLength=minLineLength, maxLineGap=0)  # rho is set to 3 to detect more lines, easier to get more then filter them out later

    #for testing purposes, show all found lines
    # for i in range(0, len(lines)):
    #   for x1, y1, x2, y2 in lines[i]:
    #      cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
    #      cv2.imwrite('gauge-%s-lines-test.%s' %(gauge_number, file_type), img)

    # remove all lines outside a given radius
    final_line_list = []
    #print "radius: %s" %r

    diff1LowerBound = 0.15 #diff1LowerBound and diff1UpperBound determine how close the line should be from the center
    diff1UpperBound = 0.25
    diff2LowerBound = 0.5 #diff2LowerBound and diff2UpperBound determine how close the other point of the line should be to the outside of the gauge
    diff2UpperBound = 1.0
    for i in range(0, len(lines)):
        for x1, y1, x2, y2 in lines[i]:
            diff1 = distance2Points(x, y, x1, y1)  # x, y is center of circle
            diff2 = distance2Points(x, y, x2, y2)  # x, y is center of circle
            #set diff1 to be the smaller (closest to the center) of the two), makes the math easier
            if (diff1 > diff2):
                temp = diff1
                diff1 = diff2
                diff2 = temp
            # check if line is within an acceptable range
            if (((diff1<diff1UpperBound*r) and (diff1>diff1LowerBound*r) and (diff2<diff2UpperBound*r)) and (diff2>diff2LowerBound*r)):
                line_length = distance2Points(x1, y1, x2, y2)
                # add to final list
                final_line_list.append([x1, y1, x2, y2])

    #testing only, show all lines after filtering
    # for i in range(0,len(final_line_list)):
    #     x1 = final_line_list[i][0]
    #     y1 = final_line_list[i][1]
    #     x2 = final_line_list[i][2]
    #     y2 = final_line_list[i][3]
    #     cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)

    # assumes the first line is the best one
    x1 = final_line_list[0][0]
    y1 = final_line_list[0][1]
    x2 = final_line_list[0][2]
    y2 = final_line_list[0][3]
    cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)

    #for testing purposes, show the line overlayed on the original image
    #cv2.imwrite('gauge-1-test.jpg', img)
    #cv2.imwrite('C:/Users/okarademirci/Desktop/analog-gauge-reader/images/gauge-%s-lines-2.%s' % (gauge_number, file_type), img)

    #find the farthest point from the center to be what is used to determine the angle
    dist_pt_0 = distance2Points(x, y, x1, y1)
    dist_pt_1 = distance2Points(x, y, x2, y2)
    if (dist_pt_0 > dist_pt_1):
        x_angle = x1 - x
        y_angle = y - y1
    else:
        x_angle = x2 - x
        y_angle = y - y2
    # take the arc tan of y/x to find the angle
    res = numpy.arctan(numpy.divide(float(y_angle), float(x_angle)))
    #np.rad2deg(res) #coverts to degrees

    # print x_angle
    # print y_angle
    # print res
    # print np.rad2deg(res)

    #these were determined by trial and error
    res = numpy.rad2deg(res)
    if x_angle > 0 and y_angle > 0:  #in quadrant I
        final_angle = 270 - res
    if x_angle < 0 and y_angle > 0:  #in quadrant II
        final_angle = 90 - res
    if x_angle < 0 and y_angle < 0:  #in quadrant III
        final_angle = 90 - res
    if x_angle > 0 and y_angle < 0:  #in quadrant IV
        final_angle = 270 - res

    #print final_angle

    old_min = float(min_angle)
    old_max = float(max_angle)

    new_min = float(min_value)
    new_max = float(max_value)

    old_value = final_angle

    old_range = (old_max - old_min)
    new_range = (new_max - new_min)
    new_value = (((old_value - old_min) * new_range) / old_range) + new_min

    return new_value


def main():

    # 1) get the image from directory.
    image = getImage()

    min_angle,max_angle,min_value,max_value,units = setStaticUserRealGaugeDetails()

    # 2) covnert the image to gray .    
    # 3) find the circle in the image with customization
    x,y,r = getCircleAndCustomize(image)
    # 4) find the line in the circle.
    # 5) find the value in the range of guage
    newValue = get_current_value(image,min_angle,max_angle,min_value,max_value,x,y,r)
    print(newValue)

if __name__=='__main__':
    main()