python - opencv python使用roxPolyDP在植物托盘中找到正方形

标签 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(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)

没有错误,只是产生的图像不能正确识别所有非常清晰的正方形。
谁能看到我犯的错误?

更新后的图像如下所示:

最佳答案

您可以通过一些简单的修改就可以大大提高结果(和性能)。

首先,阈值图像中的“网格”在行中具有大量噪声和缺陷。您可以使用morhpological opening进行改进。同样,仅搜索外部轮廓就足以满足此图像的要求(尽管对于其他图像可能不行)。

接下来,检测正方形的方法似乎相当复杂,我认为这很严格。由于孔是正方形,因此您可以简单地将宽度除以轮廓的boundingRect的高度,该高度应接近1。

结果-找到的正方形被染成灰色:

enter image description here

码:

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()

关于python - opencv python使用roxPolyDP在植物托盘中找到正方形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58940891/

相关文章:

image - 如何使用opencv或其他开源库基于运动计算形状?

r - 已知植物位置的裁剪行检测 - 如何?

python - 如果不关闭 pyodbc 连接会发生什么情况?

python - 使用 R 抓取 PDF

Python:读取带有日期/时间的二进制文件

python - discord.py - 获取用户的 channel 权限

c++ - OpenCV 3.0 中缺少非自由模块

iphone - openCV CvSVM::save为iPhone生成太大的文件

matlab - 旋转后如何在图像上找到一个点?

c++ - OpenCV(C++)中的背景减法