如何在 opencv python 中获取低对比度图像的边缘

How can I get the edges of low contrast image in opencv python

我正在尝试从 TEM(显微镜)图像中获取此对象的边缘,问题是接触面很低,尤其是在上边缘,我尝试了几种阈值处理、对比度均衡...但是我无法获得上边缘。

N.B: 我正在尝试计算液滴和管之间的角度 我不确定这是否是解决此问题的最佳方法.

原图:

我得到的Canny边缘检测:

我得到这个结果的步骤是:

  1. 对比度增强
  2. 阈值
  3. 高斯滤波器
  4. Canny 边缘检测

代码:

clahe = cv2.createCLAHE(clipLimit=clip_limit, tileGridSize=(grid_size, grid_size))
equ = clahe.apply(img)
val = filters.threshold_otsu(equ)
mask = img < val
# denoising part
mask = filters.gaussian(mask,sigma=sigmaG)
# edge detection
edge = feature.canny(mask,sigma=sigmaC)
edge = img_as_ubyte(edge)

我们有这张图片,我们想要检测麦克风的边缘:

基本上,我将图像转换为灰度,添加高斯模糊,并使用 canny 边缘检测器检测边缘。一个更重要的部分是通过扩张边缘然后腐蚀它们来填充检测到的边缘中的间隙。

以上都是在process函数中实现的; draw_contours函数基本上利用了process函数,检测最大轮廓:

import cv2
import numpy as np

def process(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    img_blur = cv2.GaussianBlur(img_gray, (11, 11), 7)
    img_canny = cv2.Canny(img_blur, 0, 42)
    kernel = np.ones((19, 19))
    img_dilate = cv2.dilate(img_canny, kernel, iterations=4)
    img_erode = cv2.erode(img_dilate, kernel, iterations=4)
    return img_erode

def draw_contours(img):
    contours, hierarchies = cv2.findContours(process(img), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    cnt = max(contours, key=cv2.contourArea)
    peri = cv2.arcLength(cnt, True)
    approx = cv2.approxPolyDP(cnt, 0.004 * peri, True)
    cv2.drawContours(img, [approx], -1, (255, 255, 0), 2)

img = cv2.imread("image.jpg")
h, w, c = img.shape

img = cv2.resize(img, (w // 2, h // 2))
draw_contours(img)

cv2.imshow("Image", img)
cv2.waitKey(0)

输出:

您可以通过调整 process 函数中的一些值来省略掉落。例如,值

def process(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    img_blur = cv2.GaussianBlur(img_gray, (11, 11), 10)
    img_canny = cv2.Canny(img_blur, 0, 38)
    kernel = np.ones((13, 13))
    img_dilate = cv2.dilate(img_canny, kernel, iterations=3)
    img_erode = cv2.erode(img_dilate, kernel, iterations=4)
    return img_erode

输出: