python - 如何使用 Opencv 和 Python 检测图像中的白色区域?

标签 python opencv machine-learning image-processing computer-vision

我正在尝试提取图像中大白色区域的坐标,如下所示: 这是原始图像:

Original Image

使用小方核,我应用闭合操作来填充小孔并帮助识别图像中的较大结构,如下所示:

import cv2
import numpy as np
import imutils 

original = cv2.imread("Plates\\24.png")
original = cv2.resize(original, None, fx=3, fy=3, interpolation=cv2.INTER_CUBIC)
gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY)
    
# next, find regions in the image that are light
squareKern = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
light = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, squareKern)
light = cv2.threshold(light, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]

生成的图片如下:

Resulting Image 1

这是另一个例子:

Resulting Image 2

我希望能够做的是检测板中的大白色区域,如下所示:

Needed output

请记住,轮廓不适用于许多示例

最佳答案

使用您提供的一张图片:

enter image description here

关于如何解决这个问题,我提出了两种方法:

方法一

轮廓面积比较

如您所见,图像中有 3 个大轮廓;顶部矩形及其下方的两个矩形,您希望将其作为一个整体进行检测。

所以我在你的图像上使用了一个阈值,检测了阈值图像的轮廓,并索引了第二大轮廓和第三大轮廓(最大的是你想要忽略的顶部矩形)。

这是阈值图像:

enter image description here

我将两个轮廓叠加在一起并检测了两个轮廓的边界框:

import cv2
import numpy as np

img = cv2.imread("image.png")

def process(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    _, thresh = cv2.threshold(img_gray, 128, 255, cv2.THRESH_BINARY)
    img_blur = cv2.GaussianBlur(thresh, (5, 5), 2)
    img_canny = cv2.Canny(img_blur, 0, 0)
    return img_canny

def get_contours(img):
    contours, _ = cv2.findContours(process(img), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    r1, r2 = sorted(contours, key=cv2.contourArea)[-3:-1]
    x, y, w, h = cv2.boundingRect(np.r_[r1, r2])
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)

get_contours(img)
cv2.imshow("img_processed", img)
cv2.waitKey(0)

输出:

enter image description here


方法二

阈值掩蔽

由于底部的 2 个矩形比盘子的顶部矩形更白,我使用了一个阈值来遮盖盘子的顶部:

enter image description here

我在上面显示的蒙版上使用了 canny 边缘检测器。

import cv2

def process(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    _, thresh = cv2.threshold(img_gray, 163, 255, cv2.THRESH_BINARY)
    img_canny = cv2.Canny(thresh, 0, 0)
    img_dilate = cv2.dilate(img_canny, None, iterations=7)
    return cv2.erode(img_dilate, None, iterations=7)

def get_contours(img):
    contours, _ = cv2.findContours(process(img), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    x, y, w, h = cv2.boundingRect(max(contours, key=cv2.contourArea))
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)

img = cv2.imread("egypt.png")
get_contours(img)
cv2.imshow("img_processed", img)
cv2.waitKey(0)

输出:

enter image description here

当然,如果板的顶部不比底部亮,则此方法可能无法正常工作。

关于python - 如何使用 Opencv 和 Python 检测图像中的白色区域?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67457125/

相关文章:

python - 检查numpy数组是否连续?

opencv - 根据所选坐标裁剪图像

r - 将决策树节点映射到独热向量的最快方法是什么?

python - 如何在命令行python中接受按键?

python - 自动更正 Python 中的缩进错误

android - 如何解决以非零退出值2/退出值-1完成的 “Android/Sdk/ndk-bundle/ndk-build.cmd”

python - OpenCv代码抛出分割错误(核心转储)Ubuntu 14.04

machine-learning - 哪些分类器提供权重向量?

Python Sklearn : Understanding of d-tree Output for Categorical Variable

python - docker 中的 django 迁移权限被拒绝