Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.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 如何找到像钻头这样的金属零件的精确边缘/二元阈值?_Python_Opencv_Image Processing_Edge Detection_Image Thresholding - Fatal编程技术网

Python 如何找到像钻头这样的金属零件的精确边缘/二元阈值?

Python 如何找到像钻头这样的金属零件的精确边缘/二元阈值?,python,opencv,image-processing,edge-detection,image-thresholding,Python,Opencv,Image Processing,Edge Detection,Image Thresholding,我是OpenCV和python新手,所以请像12年级学生一样帮助我。我的问题是,我想检测出正确的阈值或测量对象的边缘,但我所做的工作会在图像中产生大量噪声,因此我无法找到正确的对象 我试着去除图像中的眩光,然后直方图均衡化,然后尝试自适应阈值 gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) h,s,v=cv2.split(cv2.cvtColor(img, cv2.COLOR_BGR2HSV)) bgi=cv2.GaussianBlur(gray, (3,

我是OpenCV和python新手,所以请像12年级学生一样帮助我。我的问题是,我想检测出正确的阈值或测量对象的边缘,但我所做的工作会在图像中产生大量噪声,因此我无法找到正确的对象

我试着去除图像中的眩光,然后直方图均衡化,然后尝试自适应阈值

gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
h,s,v=cv2.split(cv2.cvtColor(img, cv2.COLOR_BGR2HSV))

bgi=cv2.GaussianBlur(gray, (3, 3), 1.0)
rn_gr = cv2.fastNlMeansDenoising(bgi,None,10,7,21)

equ = cv2.equalizeHist(rn_gr)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
cl1 = clahe.apply(rn_gr)

nonSat = s < 40
disk = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))    
nonSat = cv2.erode(nonSat.astype(np.uint8), disk) 
v2 = v.copy()    
v2[nonSat == 0] = 0;  
glare = v2 > 200;
glare = cv2.dilate(glare.astype(np.uint8), disk);
glare = cv2.dilate(glare.astype(np.uint8), disk);    
corrected = cv2.inpaint(img, glare, 5, cv2.INPAINT_NS)
object=corrected[485:1665,225:335]
gray_co=cv2.cvtColor(object, cv2.COLOR_BGR2GRAY)
bgi_co=cv2.GaussianBlur(gray_co, (3, 3), 1.0)
rn_gr_co = cv2.fastNlMeansDenoising(bgi_co,None,10,7,21)
cl2 = clahe.apply(rn_gr_co)

v=np.median(cl2)
lower=int(max(0,(1.0-sigma)*v))
upper=int(min(255,(1.0+sigma)*v))
print(lower,upper)
edged = cv2.Canny(cl2,lower,upper)
th3_o = cv2.adaptiveThreshold(obj,upper,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
        th3_o=~th3_o

#kernel = np.ones((5,5),np.uint8)
kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
morph = cv2.morphologyEx(th3_o, cv2.MORPH_GRADIENT, kernel)
closing = cv2.morphologyEx(th3_o, cv2.MORPH_CLOSE, kernel)
opening = cv2.morphologyEx(closing, cv2.MORPH_OPEN, kernel)

contours_o, hierarchy = cv2.findContours(th3_o,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
for cnt_o in contours_o:
   epsilon = 0.1*cv2.arcLength(cnt_o,True)
   approx = cv2.approxPolyDP(cnt_o,epsilon,True)
   con_o = cv2.drawContours(th3_o, contours_o, -1, (0,255,0), 3)
plt.imshow(con_o)
plt.show()
gray=cv2.cvt颜色(img,cv2.COLOR\u bgr2灰色)
h、 s,v=cv2.split(cv2.cvt颜色(img,cv2.COLOR_BGR2HSV))
bgi=cv2.GaussianBlur(灰色,(3,3,1.0)
rn_gr=cv2。快速平均噪声(bgi,无,10,7,21)
等式=cv2.均衡历史(rn\U gr)
clahe=cv2.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))
cl1=分类应用(rn\U gr)
nonSat=s<40
disk=cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
非Sat=cv2.腐蚀(非Sat.astype(np.uint8),圆盘)
v2=v.copy()
v2[nonSat==0]=0;
眩光=v2>200;
眩光=cv2.扩张(眩光A型(np.uint8),圆盘);
眩光=cv2.扩张(眩光A型(np.uint8),圆盘);
校正=cv2.修复(img,眩光,5,cv2.修复)
对象=已更正[485:1665225:335]
灰色\u co=cv2.CVT颜色(对象,cv2.COLOR\u BGR2GRAY)
bgi_co=cv2.GaussianBlur(gray_co,(3,3),1.0)
rn_gr_co=cv2。快速方法去噪(bgi_co,无,10,7,21)
cl2=分类申请(注册登记公司)
v=np.中值(cl2)
下限=整数(最大值(0,(1.0西格玛)*v))
上限=整数(最小值(255,(1.0+西格玛)*v))
打印(下、上)
边缘=cv2.Canny(cl2,下部,上部)
th3_o=cv2.自适应阈值(obj,上限,cv2.自适应阈值高斯阈值C,cv2.阈值二进制,11,2)
th3_o=~th3_o
#内核=np.ones((5,5),np.uint8)
kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
形态=cv2.morphologyEx(th3_o,cv2.morph_梯度,内核)
closing=cv2.morphologyEx(th3_o,cv2.MORPH_CLOSE,kernel)
opening=cv2.morphologyEx(closing,cv2.MORPH_OPEN,kernel)
轮廓,层次=cv2.查找轮廓(th3\u o,cv2.检索列表,cv2.链近似\u简单)
对于轮廓中的cnt_o:
ε=0.1*cv2.弧长(cnt_o,真)
近似=cv2.近似聚合(cnt_o,ε,真)
con_o=cv2.绘制等高线(th3_o,等高线_o,-1,(0255,0),3)
展览策划(con_o)
plt.show()

我的预期结果应该像我用边界绘制的图片,但我得到的是这样的东西

我认为你使用了太多的操作,并且过度思考了检测轮廓的方法。您使用了太多的顺序操作,而没有实现每个步骤的目标。通常,对图像进行预处理以去除噪声或平滑图像(高斯/中值/双边模糊)。然后对图像进行二值分割以分离轮廓(阈值分割、Canny边缘检测)。从这里,可以做进一步过滤或增强,如腐蚀或膨胀。然后,您可以找到轮廓并进行附加过滤(轮廓面积、接近度、纵横比)。对于这个问题,我们的想法是用一种策略性的方法保持它的简单性,以便隔离外部轮廓


这里有一个潜在的方法

  • 转换为灰度和中值模糊图像以消除噪声并平滑图像
  • 阈值图像
  • 寻找轮廓

漂亮的结果这回答了一部分,那么钻头的内部诊断又如何呢。如何检测它们?一个想法是提取钻头的ROI,因为我们有轮廓,从这里可以做颜色阈值来提取较暗的区域。然后,您可以使用Canny边缘检测来查找对角线的轮廓,并使用额外的过滤(如轮廓区域)来确保仅抓取对角线。我想我明白你的意思了,我会尝试一下,但是如果你能像你已经做过的那样给我看结果,那就容易多了。在图像处理中有两个常见的误解:1)边缘检测有效。它没有!二值化/轮廓跟踪有时有效。2) 一个算法可以猜测你的想法(例如只选择你想要的内部边缘)。像上面图像中的Diagnol一样,在图像二值化后,如何确定内部边缘。例如,是否有一种修剪算法只找到连接的循环边?请参见误解2。您试图测量边的精度是多少?你如何知道钻头的真实尺寸?你是想根据一些工业标准来测量吗?假设你能足够准确地找到图像边缘,你会遇到光学方面的问题。即使使用背光在浅色背景下使零件变暗,零件直径也会略小于真实尺寸。我正在尝试达到1/10 mm的精度。我已经使用游标卡尺计算了真实尺寸。是的,我试着按照行业标准来测量。什么样的视力问题?但我想我已经校准了相机的镜头失真。你有什么建议?
import cv2

image = cv2.imread('1.jpg')

blur = cv2.medianBlur(image, 7)
gray = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray,160,255, cv2.THRESH_BINARY_INV)[1]

cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:
    cv2.drawContours(image, [c], -1, (36, 255, 12), 2)

cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.imwrite('image.png', image)
cv2.waitKey()