OpenCV 将图像边界与检测到的对象连接起来

问题描述 投票:0回答:1

我正在使用 OpenCV 检测图片中的一些裂缝。图片是 .TIF 文件,因为它来自显微镜。图片中有多处裂缝,正在检测中。但是边界连接到一些检测到的对象,将它们组合到一个非常大的检测到的对象/“裂缝”。

这是我的代码:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

src = cv.imread('cracks.TIF', cv.IMREAD_GRAYSCALE) 

ret, th1 = cv.threshold(src, 95, 255, cv.THRESH_BINARY)

kernel = np.ones((2, 2), np.uint8)
closing = cv.morphologyEx(th1, cv.MORPH_CLOSE, kernel, iterations=2)

contours, hierarchy = cv.findContours(closing, cv.RETR_LIST, cv.CHAIN_APPROX_NONE)

overlay = src.copy()
cont = cv.drawContours(overlay, contours, -1, (0, 255, 0), 1)

titles = ["ORIGINAL", "THRESH_BINARY", "CLOSING" , "CONTOURS"]
images = [src, th1, closing, overlay]

for i in range(len(images)):
    plt.subplot(2, 2, i+1), plt.imshow(images[i])
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()

这是输出:

Crack detection

当我放大裂缝检测时,脚本也会检测到边界并将其连接到从图像中切出的裂缝:

border detected

我上传了图片,所以你可以用我的脚本自己试试。

https://ufile.io/slbfwn38

我尝试了一些不同的东西,但我无法让它正常工作。我想我遗漏了一些关于 OpenCV 如何运作但无法弄清楚的基本知识。

python opencv find border detection
1个回答
1
投票

问题与边界无关,但与

findContours
找到白色轮廓(而不是黑色轮廓)的事实有关。

th1
几乎全是白色,所以它被检测为一个大轮廓。

  • cv.THRESH_BINARY
    替换为
    cv.THRESH_BINARY_INV
    以在
    th1
    中反转黑白:

     ret, th1 = cv.threshold(src, 95, 255, cv.THRESH_BINARY_INV)
    
  • 用开代替闭形态运算(开相当于黑白颠倒时的闭):

     opening = cv.morphologyEx(th1, cv.MORPH_OPEN, kernel, iterations=2)
    

代码示例:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

src = cv.imread('cracks.TIF', cv.IMREAD_GRAYSCALE) 

ret, th1 = cv.threshold(src, 95, 255, cv.THRESH_BINARY_INV)

kernel = np.ones((2, 2), np.uint8)
#closing = cv.morphologyEx(th1, cv.MORPH_CLOSE, kernel, iterations=2)
opening = cv.morphologyEx(th1, cv.MORPH_OPEN, kernel, iterations=2)  # Use opening instead of closing because of inverted black/white

contours, hierarchy = cv.findContours(opening, cv.RETR_LIST, cv.CHAIN_APPROX_NONE)

#overlay = src.copy()
overlay = cv.cvtColor(src, cv.COLOR_GRAY2BGR)  # Convert to BGR before drawing contours
cont = cv.drawContours(overlay, contours, -1, (0, 255, 0), 1)  # Draw contours with green color

titles = ["ORIGINAL", "THRESH_BINARY", "OPENING" , "CONTOURS"]
images = [src, th1, opening, overlay]

for i in range(len(images)):
    plt.subplot(2, 2, i+1), plt.imshow(images[i])
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()

输出:

© www.soinside.com 2019 - 2024. All rights reserved.