Python 使用opencv从图像中检测长方体

Python 使用opencv从图像中检测长方体,python,opencv,image-processing,deep-learning,computer-vision,Python,Opencv,Image Processing,Deep Learning,Computer Vision,我需要使用opencv在以下图像中查找框。我尝试过使用mser,但没有得到任何好的结果。 我的MSER代码: mser = cv2.MSER_create() img = cv2.imread('Lines.png') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) I = img.copy() regions, _ = mser.detectRegions(I) hulls = [cv2.convexHull(p.reshape(-1, 1, 2))

我需要使用
opencv
在以下图像中查找框。我尝试过使用mser,但没有得到任何好的结果。

我的MSER代码:

mser = cv2.MSER_create()
img = cv2.imread('Lines.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
I = img.copy()
regions, _ = mser.detectRegions(I)
hulls = [cv2.convexHull(p.reshape(-1, 1, 2)) for p in regions]
mask = np.zeros((img.shape[0], img.shape[1], 1), dtype=np.uint8)
c=0
points=[]
for contour in hulls:
    [x, y, w, h] = cv2.boundingRect(contour)
    if w < 50 or h < 8 or w>120:
        continue
    c=c+1
    cv2.rectangle(I, (x, y), (x + w, y + h), (255, 0, 255), 0)
plt.figure(1,figsize=(100, 50))
plt.imshow(I)
mser=cv2.mser\u create()
img=cv2.imread('Lines.png')
灰色=cv2.CVT颜色(img,cv2.COLOR\U BGR2GRAY)
I=img.copy()
区域,u=mser.检测区域(I)
外壳=[cv2.convexHull(p.Reformate(-1,1,2))表示区域中的p]
掩码=np.0((img.shape[0],img.shape[1],1),dtype=np.uint8)
c=0
点数=[]
对于船体中的轮廓:
[x,y,w,h]=cv2.boundingRect(轮廓)
如果w<50或h<8或w>120:
持续
c=c+1
cv2.矩形(I,(x,y),(x+w,y+h),(255,0,255),0)
plt.图(1,figsize=(100,50))
plt.imshow(一)
MSER的结果:

您可以使用opencv提供的
cv2.findContours()
函数。您可以使用他们的教程来了解更多信息。干杯。

您可以使用opencv提供的
cv2.findContours()
函数。您可以使用他们的教程来了解更多信息。干杯。

由于输入图像已反转,请使用带有适当结构元素的“放大”来放大极值区域,然后应用MSER

由于输入图像是反转的,请使用带有适当结构元素的“放大”来放大极值区域,然后应用MSER

您可以设置图像阈值,并反转黑白像素,使方框以黑线分隔:

然后,您可以使用
cv2.findContours()
搜索轮廓,然后仅绘制符合您的尺寸标准的轮廓。您可以使用
cv2.contourArea()
获得轮廓的大小。那些轮廓是你的盒子。干杯

示例代码:

import cv2

img = cv2.imread('table.png')
resize = cv2.resize(img, None, fx=0.3, fy=0.3, interpolation = cv2.INTER_CUBIC)
gray = cv2.cvtColor(resize, cv2.COLOR_BGR2GRAY)
_,thresh = cv2.threshold(gray,50,255,cv2.THRESH_BINARY_INV)
_, contours, _ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

for cnt in contours:
    size = cv2.contourArea(cnt)
    if 100 < size < 30000:
        cv2.drawContours(resize, [cnt], 0, (0,255,0), 1)

cv2.imshow('img', resize)
导入cv2
img=cv2.imread('table.png')
调整大小=cv2.调整大小(img,无,fx=0.3,fy=0.3,插值=cv2.内部立方)
灰色=cv2.CVT颜色(调整大小,cv2.COLOR\u BGR2GRAY)
_,thresh=cv2.阈值(灰色,50255,cv2.thresh\u二进制\u INV)
_,等高线,u=cv2.查找到的多边形(阈值,cv2.重树,cv2.链近似值\u简单)
对于轮廓中的cnt:
尺寸=cv2。轮廓面积(cnt)
如果100<尺寸<30000:
cv2.绘制轮廓(调整大小[cnt],0,(0255,0),1)
cv2.imshow('img',调整大小)
结果:


您可以设置图像阈值,反转黑白像素,使方框以黑线分隔:

然后,您可以使用
cv2.findContours()
搜索轮廓,然后仅绘制符合您的尺寸标准的轮廓。您可以使用
cv2.contourArea()
获得轮廓的大小。那些轮廓是你的盒子。干杯

示例代码:

import cv2

img = cv2.imread('table.png')
resize = cv2.resize(img, None, fx=0.3, fy=0.3, interpolation = cv2.INTER_CUBIC)
gray = cv2.cvtColor(resize, cv2.COLOR_BGR2GRAY)
_,thresh = cv2.threshold(gray,50,255,cv2.THRESH_BINARY_INV)
_, contours, _ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

for cnt in contours:
    size = cv2.contourArea(cnt)
    if 100 < size < 30000:
        cv2.drawContours(resize, [cnt], 0, (0,255,0), 1)

cv2.imshow('img', resize)
导入cv2
img=cv2.imread('table.png')
调整大小=cv2.调整大小(img,无,fx=0.3,fy=0.3,插值=cv2.内部立方)
灰色=cv2.CVT颜色(调整大小,cv2.COLOR\u BGR2GRAY)
_,thresh=cv2.阈值(灰色,50255,cv2.thresh\u二进制\u INV)
_,等高线,u=cv2.查找到的多边形(阈值,cv2.重树,cv2.链近似值\u简单)
对于轮廓中的cnt:
尺寸=cv2。轮廓面积(cnt)
如果100<尺寸<30000:
cv2.绘制轮廓(调整大小[cnt],0,(0255,0),1)
cv2.imshow('img',调整大小)
结果:


我认为可以使用像素模式来识别方框。在本例中,通过图像中的每个像素,当您得到一个白色像素时,在x轴和y轴上找到下一个像素的颜色。如果两个都是白色,则将像素视为方块的第一个像素。然后取x轴的下一个像素,找到y轴的像素。如果它是白色的,那么你必须到达盒子的另一个角落。如果像素不是白色,那么考虑下一个X轴像素。当你在角落里,然后找到下一个y轴像素,直到你到达角落。当你在第三角时考虑上一个X像素。然后找到上一个x像素,直到到达第四个角。然后,您可以通过四个角的像素坐标保存长方体。我认为这更准确。但这既耗时又复杂。但这可能是一种新的算法。(这仅在框是直线时有效)

我认为可以使用像素模式来识别框。在本例中,通过图像中的每个像素,当您得到一个白色像素时,在x轴和y轴上找到下一个像素的颜色。如果两个都是白色,则将像素视为方块的第一个像素。然后取x轴的下一个像素,找到y轴的像素。如果它是白色的,那么你必须到达盒子的另一个角落。如果像素不是白色,那么考虑下一个X轴像素。当你在角落里,然后找到下一个y轴像素,直到你到达角落。当你在第三角时考虑上一个X像素。然后找到上一个x像素,直到到达第四个角。然后,您可以通过四个角的像素坐标保存长方体。我认为这更准确。但这既耗时又复杂。但这可能是一种新的算法。(这仅在框是直线的情况下有效)

因为您已经有了一个二值图像,我将尝试
cv::findContours
并仅保留可以简化的轮廓,例如使用4点的道格拉斯·佩克算法。我有一个代码,但只有在C++中。在Python中,你可以使用CV2.FixTrror函数,因为你已经有了二进制图像,我会尝试<代码> CV::FixDeCouss/Cuff>,并且只保留可以用Douglas Peucker算法简化的等高线,使用4点。我有一个代码,但只有C++。在Python中,你可以使用CV2.FixTrimes函数。