简体   繁体   English

OpenCV - 在相似图像中找不到正确的轮廓

[英]OpenCV - Can't find correct contours in similar images

the task I want to do looks pretty simple: I take as input several images with an object centered in the photo and a little color chart needed for other purposes.我想做的任务看起来很简单:我将几个图像作为输入,其中一个对象位于照片的中心,还有一个用于其他目的的小颜色图表。 My code normally works for the majority of the cases, but sometimes fails miserably and I just can't understand why.我的代码通常适用于大多数情况,但有时会失败,我就是不明白为什么。

For example (these are the source images), it works correctly on this https://imgur.com/PHfIqcb but not on this https://imgur.com/qghzO3V例如(这些是源图像),它可以在这个https://imgur.com/PHfIqcb上正常工作,但不能在这个https://imgur.com/qghzO3V

Here's the code of the interested part:这是感兴趣部分的代码:

img = cv2.imread(path)
height, width, channel = img.shape
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

kernel = np.ones((31, 31), np.uint8)
dil = cv2.dilate(gray, kernel, iterations=1)
_, th = cv2.threshold(dil, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
th_er1 = cv2.bitwise_not(th)

_, contours, _= cv2.findContours(th_er1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
areas = [cv2.contourArea(c) for c in contours]
max_index = np.argmax(areas)
cnt=contours[max_index]

x,y,w,h = cv2.boundingRect(cnt)

After that I'm just going to crop the image accordingly to the given results (getting the biggest rectangle contour), basically cutting off the photo only the main object.之后,我将根据给定的结果裁剪图像(获得最大的矩形轮廓),基本上只剪掉主要对象的照片。

But as I said, using very similar images sometimes works and sometimes not.但正如我所说,使用非常相似的图像有时有效,有时无效。

Thank you in advance.先感谢您。

也许您可以尝试不使用 otsu 的方法,而只需手动设置阈值,如果可能的话... ;)

You can use the Canny edge detector.您可以使用 Canny 边缘检测器。 In the two images, there is a good threshold value to isolate the object in the center of the image.在两幅图像中,都有一个很好的阈值来隔离图像中心的物体。 After applying the threshold, we blur the results and apply the Canny edge detector before finding the contours:应用阈值后,我们模糊结果并在找到轮廓之前应用Canny 边缘检测器

import cv2
import numpy as np

def process(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    _, thresh = cv2.threshold(img_gray, 190, 255, cv2.THRESH_BINARY_INV)
    img_blur = cv2.GaussianBlur(thresh, (3, 3), 1)
    img_canny = cv2.Canny(img_blur, 0, 0)
    kernel = np.ones((5, 5))
    img_dilate = cv2.dilate(img_canny, kernel, iterations=1)
    return cv2.erode(img_dilate, kernel, iterations=1)

def get_contours(img):
    contours, hierarchies = cv2.findContours(process(img), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    cnt = max(contours, key=cv2.contourArea)
    cv2.drawContours(img, [cnt], -1, (0, 255, 0), 30)
    x, y, w, h = cv2.boundingRect(cnt)
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 30)

img = cv2.imread("image.jpeg")
get_contours(img)
cv2.imshow("Result", img)
cv2.waitKey(0)

Input images:输入图像:

Output images:输出图像:

在此处输入图像描述

在此处输入图像描述

The green outlines are the contours of the objects, and the red outlines are the bounding boxes of the objects.绿色轮廓是物体的轮廓,红色轮廓是物体的边界框。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM