Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.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/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
opencv python使用APROXPOLYDP在植物托盘中查找正方形_Python_Opencv_Image Processing - Fatal编程技术网

opencv python使用APROXPOLYDP在植物托盘中查找正方形

opencv python使用APROXPOLYDP在植物托盘中查找正方形,python,opencv,image-processing,Python,Opencv,Image Processing,我试图在这样一张图像中识别托盘中设备井的边界: 当我运行阈值处理时,图像如下所示: 但是,当我尝试在原始图像上绘制轮廓时,输出是不完整的。我相信这个图像足够清晰,可以很好地工作,但我找不到哪里出了问题。这是我的密码: def angle_cos(p0, p1, p2): d1, d2 = (p0-p1).astype('float'), (p2-p1).astype('float') return abs( np.dot(d1, d2) / np.sqrt( np.dot(d

我试图在这样一张图像中识别托盘中设备井的边界:

当我运行阈值处理时,图像如下所示:

但是,当我尝试在原始图像上绘制轮廓时,输出是不完整的。我相信这个图像足够清晰,可以很好地工作,但我找不到哪里出了问题。这是我的密码:

def angle_cos(p0, p1, p2):
    d1, d2 = (p0-p1).astype('float'), (p2-p1).astype('float')
    return abs( np.dot(d1, d2) / np.sqrt( np.dot(d1, d1)*np.dot(d2, d2) ) )
def find_squares(img):
    img = cv2.GaussianBlur(img, (5, 5), 0)
    squares = []
    for gray in cv2.split(img):
        for thrs in range(0, 255, 26):
            if thrs == 0:
                bina = cv2.Canny(gray, 0, 50, apertureSize=5)
                bina = cv2.dilate(bina, None)
            else:
                _retval, bina = cv2.threshold(gray, thrs, 255, cv2.THRESH_BINARY)
            contours = cv2.findContours(bina, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
            for cnt in contours[1]:
                cnt_len = cv2.arcLength(cnt, True)
                cnt = cv2.approxPolyDP(cnt, 0.02*cnt_len, True)
                if len(cnt) == 4 and cv2.contourArea(cnt) > 1000 and cv2.isContourConvex(cnt):
                    cnt = cnt.reshape(-1, 2)
                    max_cos = np.max([angle_cos( cnt[i], cnt[(i+1) % 4], cnt[(i+2) % 4] ) for i in range(4)])
                    if max_cos < 0.1:
                        squares.append(cnt)
     return squares
squares = find_squares(ct2)
newim = cv2.drawContours(dupimage, squares, -1, (0, 0, 255), 3)
plt.figure()
plt.imshow(newim)
def角度cos(p0、p1、p2):
d1,d2=(p0-p1).aType('float'),(p2-p1).aType('float'))
返回绝对值(np.dot(d1,d2)/np.sqrt(np.dot(d1,d1)*np.dot(d2,d2)))
def查找平方(img):
img=cv2.高斯模糊(img,(5,5,0)
正方形=[]
对于cv2中的灰色。分割(img):
对于范围(0、255、26)内的THR:
如果thrs==0:
bina=cv2.Canny(灰色,0,50,光圈大小=5)
bina=cv2.扩张(bina,无)
其他:
_retval,bina=cv2.阈值(灰色,thrs,255,cv2.阈值)
轮廓=cv2.findContours(比纳、cv2.RETR\u列表、cv2.CHAIN\u近似值\u简单值)
对于轮廓中的cnt[1]:
cnt_len=cv2.弧长(cnt,真)
cnt=cv2.approxPolyDP(cnt,0.02*cnt_len,真)
如果len(cnt)=4且cv2.contourArea(cnt)>1000且cv2.isContourConvex(cnt):
cnt=cnt.重塑(-1,2)
max_cos=np.max([范围(4)]内i的角度(cnt[i],cnt[(i+1)%4],cnt[(i+2)%4]))
如果最大cos<0.1:
正方形。附加(cnt)
返回方块
正方形=查找正方形(ct2)
newim=cv2.绘制等高线(dupimage,正方形,-1,(0,0,255),3)
plt.图()
plt.imshow(newim)
没有错误,它只是生成了一个无法正确识别所有非常清晰的正方形的图像。 有人能看出我犯的错误吗

更新后的图像如下所示:


通过一些简单的修改,您可以显著提高结果(和性能)

首先,阈值图像中的“网格”在线条中有很多噪声和缺陷。你可以使用它来改进这一点。此外,仅搜索外部轮廓就可以满足此图像的要求(尽管它可能不适用于其他图像)

其次,检测正方形的方法似乎相当复杂,我认为它太严格了。由于井是正方形的,您可以简单地将宽度除以轮廓边界矩形的高度,该高度应接近1

结果-找到的正方形以灰色显示:

代码:

导入cv2
将numpy作为np导入
#加载阈值图像
img=cv2.imread('5XbZN.jpg',0)
#调整图像大小
img=cv2.resize(img,无,无,fx=0.2,fy=0.2,插值=cv2.INTER_CUBIC)
#消除噪音/关闭管路
内核=np.one((30,30))
img=cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel)
#寻找轮廓
轮廓线,hier=cv2.找到的轮廓线(img,cv2.RETR\u外部,cv2.CHAIN\u近似简单)
#如果轮廓呈方形且具有最小尺寸,则以灰色绘制轮廓
对于轮廓中的cnt:
(x,y,w,h)=cv2.boundingRect(cnt)
面积=cv2。轮廓面积(cnt)
如果abs((w/h)-1)<0.2且面积>2500:
cv2.拉深等高线(img,[cnt],0,(127),-1)
#显示图像
cv2.imshow(“Img”,Img)
cv2.等待键(0)
cv2.destroyAllWindows()

通过一些简单的修改,您可以显著提高结果(和性能)

首先,阈值图像中的“网格”在线条中有很多噪声和缺陷。你可以使用它来改进这一点。此外,仅搜索外部轮廓就可以满足此图像的要求(尽管它可能不适用于其他图像)

其次,检测正方形的方法似乎相当复杂,我认为它太严格了。由于井是正方形的,您可以简单地将宽度除以轮廓边界矩形的高度,该高度应接近1

结果-找到的正方形以灰色显示:

代码:

导入cv2
将numpy作为np导入
#加载阈值图像
img=cv2.imread('5XbZN.jpg',0)
#调整图像大小
img=cv2.resize(img,无,无,fx=0.2,fy=0.2,插值=cv2.INTER_CUBIC)
#消除噪音/关闭管路
内核=np.one((30,30))
img=cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel)
#寻找轮廓
轮廓线,hier=cv2.找到的轮廓线(img,cv2.RETR\u外部,cv2.CHAIN\u近似简单)
#如果轮廓呈方形且具有最小尺寸,则以灰色绘制轮廓
对于轮廓中的cnt:
(x,y,w,h)=cv2.boundingRect(cnt)
面积=cv2。轮廓面积(cnt)
如果abs((w/h)-1)<0.2且面积>2500:
cv2.拉深等高线(img,[cnt],0,(127),-1)
#显示图像
cv2.imshow(“Img”,Img)
cv2.等待键(0)
cv2.destroyAllWindows()

当你打印
正方形时,你会得到什么?@barny[array([[15842314],[15812578],[13062568],[13072318],[dtype=int32],[15862311],[13042316],[13062575],[1584250],[dtype=int32],[35042302],[37692308],[37502562],[34812564]],dtype=int32),数组([[35012300],[34792567],如果您上载原始图像而不是绘图,我们可以更好地帮助您。不完整轮廓的原因可能是绘图的缩放。您可以使用
cv2.imwrite('newimg.png',newimg)
保存全尺寸图像。@J.D.我替换了绘图,但我仍然面临着同样的问题:打印
正方形时会得到什么?@barny[array([[15842314],[15812578],[13062568],[13072318],[dtype=int32],[15862311],[13042316],[13062575],[15842580]、dtype=int32)、数组([35042302]、[37692308]、[37502562]、[34812564]、dtype=int32)、数组([35012300]、[34792567],如果您上载原始图像而不是绘图,我们可以更好地帮助您。不完整轮廓的原因可能是绘图缩放造成的。您可以使用
cv2.imwrite('newimg.png',newimg)
保存f
import cv2
import numpy as np
# load  threshold image
img = cv2.imread('5XbZN.jpg',0)
# resize image
img = cv2.resize(img,None,None,fx=0.2,fy=0.2, interpolation=cv2.INTER_CUBIC)
# remove noise / close lines
kernel = np.ones((30,30))
img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
# find contours
contours, hier = cv2.findContours(img,cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# if the contour is square-ish and has a minimum size, draw contours in gray
for cnt in contours:
    (x,y,w,h) = cv2.boundingRect(cnt)
    area = cv2.contourArea(cnt)
    if abs((w/h)-1) < 0.2 and area > 2500:
        cv2.drawContours(img,[cnt],0,(127),-1)

# show image
cv2.imshow('Img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()