opencv 有没有一种方法可以消除图像中不连续的元素?

9vw9lbht  于 2023-11-22  发布在  其他
关注(0)|答案(1)|浏览(98)

我正在处理图像的表面粗糙度,我使用了opencv的边缘检测功能,但它也从图像中检测到了毛孔。有没有办法去除毛孔?
picture of original image and the edges detected
我试着调整阈值,但这只是消除了侧面的边缘,使毛孔更加明显。我对opencv和这类问题还很陌生,所以这段代码的大部分都是基于我在网上看到的例子。

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

# need to add the scale to it
img = cv.imread('testim5.png', cv.IMREAD_GRAYSCALE)
blurred = ndimage.filters.gaussian_filter(img, 2, mode='nearest')
edges = cv.Canny(blurred,100,200) # adjusting thresholds will only eliminate the outside edges, not the pores

字符串
[testim5.png] https://i.stack.imgur.com/Vs6K8.png

aij0ehis

aij0ehis1#

首先,你可以使用形态学操作来确保有趣的边缘被连接起来。你可以在OpenCV的网页上阅读更多关于形态学操作的内容:https://docs.opencv.org/4.x/d9/d61/tutorial_py_morphological_ops.html
代码如下:

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
from scipy import ndimage

# Open the image
img = cv.imread('testim5.png', cv.IMREAD_GRAYSCALE)

# Note that `scipy.ndimage.filters.gaussian_filter` is deprecated, use `scipy.ndimage.gaussian_filter` instead
blurred = ndimage.gaussian_filter(img, 2, mode='nearest')
edges = cv.Canny(blurred,100,175)

# Apply morphological operation (closing) to the EDGES so they are connected
kernel = np.ones((5,3),np.uint8)
edges_closing = cv.morphologyEx(edges, cv.MORPH_CLOSE, kernel)

字符串
这样做的结果是,垂直边缘不会如此不相交,如您在下图中所见。
x1c 0d1x的数据
第二步是去除毛孔。这可以看作是一个去除小连接对象的问题,@Soltius在How to remove small connected objects using OpenCV中的解决方案效果很好。
在你的例子中,代码应该是:

# Remove smallest connected components
# To understand the following lines, look the answer of @Soltius in https://stackoverflow.com/questions/42798659/how-to-remove-small-connected-objects-using-opencv
nb_blobs, im_with_separated_blobs, stats, _ = cv.connectedComponentsWithStats(edges_closing)
sizes = stats[:, -1]
sizes = sizes[1:]
nb_blobs -= 1

# Minimum size of particles we want to keep (number of pixels).
# Here, it's a fixed value, but you can set it as you want.
min_size = 80  

final_edges = np.zeros_like(im_with_separated_blobs)
for blob in range(nb_blobs):
    if sizes[blob] >= min_size:
        final_edges[im_with_separated_blobs == blob + 1] = 255

fig, axs = plt.subplots(ncols=3)
axs[0].imshow(img, cmap='gray')
axs[1].imshow(edges, cmap='gray')
axs[2].imshow(final_edges, cmap='gray')
axs[0].set_title('Original image')
axs[1].set_title('Original edges')
axs[2].set_title('New edges')
fig.tight_layout()
plt.show()


最终边缘为:


相关问题