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/7/symfony/6.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
Python 3.x 任何照明(低或高)下对象的图像分割_Python 3.x_Opencv_Image Processing_Image Segmentation - Fatal编程技术网

Python 3.x 任何照明(低或高)下对象的图像分割

Python 3.x 任何照明(低或高)下对象的图像分割,python-3.x,opencv,image-processing,image-segmentation,Python 3.x,Opencv,Image Processing,Image Segmentation,我手头的问题是围绕一个白色球划出边界。但是这个球有不同的照明。使用canny边缘检测和圆的Hough变换,我能够在强光/部分强光下检测球,但在低照度下检测不到球 那么,谁能帮助解决这个问题呢。 下面是我尝试过的代码 img=cv2.imread('14_04_2018_10_38_51_.8242_P_B_142_17197493.png.png') cimg=img.copy() img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) edges = cv2.me

我手头的问题是围绕一个白色球划出边界。但是这个球有不同的照明。使用canny边缘检测和圆的Hough变换,我能够在强光/部分强光下检测球,但在低照度下检测不到球

那么,谁能帮助解决这个问题呢。 下面是我尝试过的代码

img=cv2.imread('14_04_2018_10_38_51_.8242_P_B_142_17197493.png.png')
cimg=img.copy()
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.medianBlur(img,5)
edges=cv2.Canny(edges,200,200)
circles = cv2.HoughCircles(edges,cv2.HOUGH_GRADIENT,1,20,
                        param1=25,param2=10,minRadius=0,maxRadius=0)

if circles is not None:
     circles = np.uint16(np.around(circles))
     for i in circles[0,:]:
         # draw the outer circle
         cv2.circle(cimg,(i[0],i[1]),i[2],(255,255,255),2)
         # draw the center of the circle
         cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3)
     cv2.imwrite('segmented_out.png',cimg)
else:
    print("no circles")
cv2.imwrite('edges_out.png',edges)
在下图中,如果球也在阴影区域,我们需要分割

输出应该类似于下面的图片


使用
灰度图像将使您受到不同的光照条件的影响

为了避免这种情况,我建议在
HSV
颜色空间中工作,然后使用
Hue
组件而不是
grayscale
图像

色调独立于灯光条件,因为它提供有关颜色的信息,而不管其
饱和度
(与图像亮度绑定的值)


可能会为您带来一些关于颜色空间的清晰信息,以及最适合用于图像分割的颜色空间。

。我们有一个白色的球。
白色本身不是一种颜色。
这里的主要因素是,什么样的光真正落在
白色球上

因为落在它上面的光的类型直接影响到你可能计划使用@magicleon上面提到的HSV这样的
颜色空间进行的提取

HSV
是您在这里进行细分的最佳选择。
使用
whiteObject=cv2.inRange(hsvImage,lowerhsv限制,upperhsv限制)

HSV下限
HSV上限
HSV颜色范围

请记住,条件
1) 单击图像时,图像具有类似的条件
2) 在提取之前,您可以覆盖HSV的所有范围

希望你有个主意

以这个例子为例

选择特定的
色调
范围从
45
60

代码

这里的色调从
45
60


我对OpenCV或Python不是很有经验,但我也在学习。可能不是很像Python的代码,但您可以尝试以下方法:

import cv2
import math

circ=0
n = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220]
img = cv2.imread("ball1.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
for i in n:   
    ret, threshold = cv2.threshold(gray,i,255,cv2.THRESH_BINARY)
    im, contours, hierarchy = cv2.findContours(threshold,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
    for j in range(0, len(contours)):
        size = cv2.contourArea(contours[j])
        if 500 < size < 5000:
            if circ > 0:
                (x,y),radius = cv2.minEnclosingCircle(contours[j])
                radius = int(radius)
                area = cv2.contourArea(contours[j])
                circif = 4*area/(math.pi*(radius*2)**2)
                if circif > circ:
                    circ = float(circif)
                    radiusx = radius
                    center = (int(x),int(y))                  
            elif circ == 0:
                (x,y),radius = cv2.minEnclosingCircle(contours[j])
                radius = int(radius)
                area = cv2.contourArea(contours[j])
                circ = 4*area/(math.pi*(radius*2)**2)
            else:
                pass
cv2.circle(img,center,radiusx,(0,255,0),2)
cv2.imshow('image', img)
cv2.waitKey(0)
cv2.detroyAllWindows()
导入cv2
输入数学
circ=0
n=[10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220]
img=cv2.imread(“ball1.jpg”)
灰色=cv2.CVT颜色(img,cv2.COLOR\U BGR2GRAY)
对于n中的i:
ret,threshold=cv2.threshold(灰色,i,255,cv2.THRESH\u二进制)
im、等高线、层次=cv2.findContours(阈值、cv2.RETR\u树、cv2.CHAIN\u近似值\u无)
对于范围(0,len(等高线))内的j:
尺寸=cv2.轮廓面积(轮廓[j])
如果500<尺寸<5000:
如果circ>0:
(x,y),半径=cv2。闭合圆(等高线[j])
半径=整数(半径)
面积=cv2。轮廓面积(轮廓[j])
circif=4*面积/(数学pi*(半径*2)**2)
如果circif>circ:
circ=浮动(circif)
半径x=半径
中心=(整数(x),整数(y))
elif circ==0:
(x,y),半径=cv2。闭合圆(等高线[j])
半径=整数(半径)
面积=cv2。轮廓面积(轮廓[j])
circ=4*面积/(数学pi*(半径*2)**2)
其他:
通过
cv2.圆(img,中心,半径X,(0255,0),2)
cv2.imshow(“图像”,img)
cv2.等待键(0)
cv2.detroyAllWindows()
它的作用是将图片转换为灰度,并对其应用不同的阈值设置。然后通过向特定轮廓添加尺寸来消除噪音。当你找到它时,你检查它的圆度(注:这不是一个科学公式),并将其与下一个圆度进行比较。完美圆应该返回结果1,因此在一个轮廓中(所有轮廓中)得到的最大数将是您的球

结果:


注意:我没有尝试增加大小限制,因此如果您有一张高分辨率图片

请添加输入图像和您的结果,那么更高的限制可能会返回更好的结果。@zindarod出于保密原因,我无法放置原始图像。不过,我会尽量把一些东西接近我正在尝试的。谢谢。这当然是我在想的台词。但是,如果图像虽然不是灰度图像,但只有灰度,那该怎么办呢?我想你是亮度的囚徒,因为灰度定义为三个通道RGB的平均值,这取决于亮度。我不理解你在那里写的代码。你能解释一下吗?谢谢。我喜欢你的回答,而且相当直截了当。但再一次考虑到我所展示的图像,如果白色的高尔夫球在高尔夫球棒的阴影下会怎样呢。那么你会选择什么样的hsv值?希望给你一个想法,这就是你所说的“这不是一个科学公式”吗
circ=4*area/(math.pi*(radius*2)**2)
--您最好忽略这些常量,因为您只是在寻找圆度的最大值:
circ=area/(radius**2)
。否则,对于圆,
area=2*pi*半径**2
,因此
circ=area/(2*pi*半径**2)
更为正确。还有其他圆度标准可能更有效。例如,如果您可以计算周长,那么
circ=4*pi*area/(周长**2)
是一个不错的选择。它是1表示一个完美的圆,更小表示更少的圆形。我在代码中发现了一个错误…我更新了,现在应该可以更好地工作了。它应该是“if circif>circ:circ=float(corcif)”@Cris Luengo:我相信有更好的圆度算法(我不是数学家),但在图片中添加了一个白色矩形,尝试了你的公式和我的公式,在你的例子中,它是
import cv2
import math

circ=0
n = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220]
img = cv2.imread("ball1.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
for i in n:   
    ret, threshold = cv2.threshold(gray,i,255,cv2.THRESH_BINARY)
    im, contours, hierarchy = cv2.findContours(threshold,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
    for j in range(0, len(contours)):
        size = cv2.contourArea(contours[j])
        if 500 < size < 5000:
            if circ > 0:
                (x,y),radius = cv2.minEnclosingCircle(contours[j])
                radius = int(radius)
                area = cv2.contourArea(contours[j])
                circif = 4*area/(math.pi*(radius*2)**2)
                if circif > circ:
                    circ = float(circif)
                    radiusx = radius
                    center = (int(x),int(y))                  
            elif circ == 0:
                (x,y),radius = cv2.minEnclosingCircle(contours[j])
                radius = int(radius)
                area = cv2.contourArea(contours[j])
                circ = 4*area/(math.pi*(radius*2)**2)
            else:
                pass
cv2.circle(img,center,radiusx,(0,255,0),2)
cv2.imshow('image', img)
cv2.waitKey(0)
cv2.detroyAllWindows()