在OPEN CV PYTHON中识别颜色检测中的圆

在OPEN CV PYTHON中识别颜色检测中的圆,python,opencv,Python,Opencv,我这里有一个检测激光的代码,但我在不同的光照条件下遇到了问题。所以我想如果我添加一个代码来检查灯光是否是圆的话,我可能会解决这个问题 问题是我不知道如何在这里应用它。这是激光在面具上的样子 我希望你能帮我写代码 这是我的密码: import cv2 import numpy as np cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() hsv = cv2.cvtColor(frame, cv2.COLO

我这里有一个检测激光的代码,但我在不同的光照条件下遇到了问题。所以我想如果我添加一个代码来检查灯光是否是圆的话,我可能会解决这个问题

问题是我不知道如何在这里应用它。这是激光在面具上的样子

我希望你能帮我写代码

这是我的密码:

import cv2
import numpy as np

cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) convert from bgr to hsv color space

    lower = np.array([0,0,255]) #range of laser light
    upper = np.array([255, 255, 255])

    mask = cv2.inRange(hsv, lower, upper) 
    maskcopy = mask.copy()

    circles = cv2.HoughCircles(maskcopy, cv2.HOUGH_GRADIENT, 1, 500,
                      param1 = 20, param2 = 10,
                      minRadius = 1, maxRadius = 3)
    _,cont,_ = cv2.findContours(maskcopy, cv2.RETR_LIST,
                            cv2.CHAIN_APPROX_SIMPLE)
    if circles is not None:
        circles = np.round(circles[0,:]).astype('int')

        for(x,y,r) in circles:
            cv2.circle(frame, (x,y), r, (0,255,0),4)

    cv2.imshow('mask', mask)
    cv2.imshow('frame', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()
截图:


我想出了一个不同方法的解决方案

我的想法是创建一个圆心位于遮罩白色区域的中心,半径等于遮罩白色区域宽度的一半。然后我检查这个圆圈和面具有多相似

代码如下:

white = np.where(mask>250) # you can also make it == 255
white = np.asarray(white)
minx = min(white[0])
maxx = max(white[0])
miny = min(white[1])
maxy = max(white[1])
radius = int((maxx-minx)/2)
cx = minx + radius
cy = miny + radius
black = mask.copy()
black[:,:]=0
cv2.circle(black, (cy,cx), radius, (255,255,255),-1)
diff = cv2.bitwise_xor(black, mask)
diffPercentage = len(diff>0)/diff.size
print (diffPercentage)
然后,您必须提出什么百分比阈值对您来说足够“相似”

上面的代码是从磁盘读取掩码测试的,但视频只是一系列图像。如果没有网络摄像头输入,我无法用视频测试代码,但它应该是这样工作的:

import cv2
import numpy as np

cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    lower = np.array([0,0,255]) #range of laser light
    upper = np.array([255, 255, 255])

    mask = cv2.inRange(hsv, lower, upper) 
    white = np.where(mask>250) # you can also make it == 255
    white = np.asarray(white)
    minx = min(white[0])
    maxx = max(white[0])
    miny = min(white[1])
    maxy = max(white[1])
    radius = int((maxx-minx)/2)
    cx = minx + radius
    cy = miny + radius
    black = mask.copy()
    black[:,:]=0
    cv2.circle(black, (cy,cx), radius, (255,255,255),-1)
    diff = cv2.bitwise_xor(black, mask)
    diffPercentage = len(diff>0)/diff.size
    print (diffPercentage)

    cv2.imshow('mask', mask)
    cvw.imshow('diff', diff)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()

我曾经尝试过类似的方法,对我来说最好的解决方案是:

(我将您的图像保存到硬盘中,并制作了一个示例代码)

因此,我们的想法是用
cv2.findContours
(激光点)找到你的轮廓并给它围上一个圆,这样你就可以得到半径,然后用
cv2.contourArea
得到你轮廓的面积,并用公式
circ=4*area/(math.pi*(radius*2)**2)
检查它的圆度。完美的circle将返回1的结果。越是变为0,轮廓的“圈”就越小(如下图所示)。希望有帮助

因此,您的代码应该是这样的,并且不会返回任何错误(尝试后,它就可以工作了)


使用Houghcirle如果我要使用它,我应该把它放在代码中的什么地方?因为有一段时间我的密码上写着@akhilesh在
maskcopy=mask.copy()
之后,您可以复制一份
maskcopy
,并可以应用该副本的
houghcirle
。我在上面编辑了我的代码,但我不确定参数中的值。介意你查一下吗(@Akhileshuse cv::findContours。检查每个轮廓是否MineConclosingCircle包含的相对数量小于零像素。这是否适用于视频中的Sir?我将把它放在哪里?是的,视频只是一系列图像。我将使用视频部分进行编辑。谢谢,先生,但我得到了以下错误:“white=np.where(mask[:,:,0]>250)#您也可以将其设置为==255索引器。错误:数组索引太多“我更改了代码。请立即尝试。真正重要的是理解这个想法。这只是因为我没有使用hsl转换和“inRange”函数测试您的代码。我没有您输入的示例来测试它。我仍然收到这些错误“索引器:数组的索引太多了”white=np.where(mask[:;0]>250)我尝试在视频中应用它,但我遇到了很多错误:(但我明白了这个想法。我尝试了,它成功了……我已经编辑并发布了我在yoursWOW中实现的代码,先生,我认为这可能是我一直在寻找的解决方案。非常感谢!很高兴我能提供帮助。干杯!
import cv2
import math

img = cv2.imread('laser.jpg')
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray_image,100,255,cv2.THRESH_BINARY)
im2, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
area = sorted(contours, key=cv2.contourArea, reverse=True)
contour = area[0]
(x,y),radius = cv2.minEnclosingCircle(contour)
radius = int(radius)
area = cv2.contourArea(contour)
circ = 4*area/(math.pi*(radius*2)**2)
cv2.drawContours(img, [contour], 0, (0,255,0), 2)
cv2.imshow('img', img)
print(circ)
import cv2
import numpy as np
import math

cap = cv2.VideoCapture(0)

while True:
    try:
        ret, frame = cap.read()
        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) #convert from bgr to hsv color space

        lower = np.array([0,0,255]) #range of laser light
        upper = np.array([255, 255, 255])

        mask = cv2.inRange(hsv, lower, upper) 

        im2, contours, hierarchy = cv2.findContours(mask,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
        area = sorted(contours, key=cv2.contourArea, reverse=True)
        contour = area[0]
        (x,y),radius = cv2.minEnclosingCircle(contour)
        radius = int(radius)
        area = cv2.contourArea(contour)
        circ = 4*area/(math.pi*(radius*2)**2)
        print(circ)
    except:
        pass

    cv2.imshow('mask', mask)
    cv2.imshow('frame', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()