我正在尝试仅使用 openCV 从图像中去除水滴和孔洞。
之前
remove_small_objects
:
我尝试过使用
remove_small_objects
:
retval, labels, stats, centroids = cv2.connectedComponentsWithStats(output_im)
cleaned = morphology.remove_small_objects(labels, 1000)
cleaned = cleaned.astype(np.uint8)
labels = (labels * 255).astype(np.uint8)
retval_cl, labels_cl, stats_cl, centroids_cl = cv2.connectedComponentsWithStats(cleaned)
remove_small_objects
之后:
作为指导,我最终应该得到这样的图像
我还没有参加测试
这有帮助吗?
片段:
import cv2
import numpy as np
from skimage import morphology
image = cv2.imread('s.png', cv2.IMREAD_GRAYSCALE)
retval, labels, stats, centroids = cv2.connectedComponentsWithStats(image)
# Remove small objects
cleaned = morphology.remove_small_objects(labels, min_size=1000)
cleaned = cleaned.astype(np.uint8)
cv2.imwrite('cleaned_image.jpg', cleaned)
要使用连接的组件,您需要将图像转换为二进制图像。我猜你的output_im是二进制图像。另外,您不需要将标签与 255 相乘。
(labels * 255)
可能会导致 uint8 溢出。
相反,您可以尝试隔离您感兴趣的区域,然后单独对其进行处理,最后将其放回原始图像大小框架。
这是,你怎么能做到这一点:
from skimage.color import rgb2gray, rgba2rgb
from skimage.io import imread
from skimage import filters, morphology, segmentation
import matplotlib.pyplot as plt
image = imread("YOUR_IMAGE_PATH")
# converting image to gray
image_rgb = rgba2rgb(image)
image_gray =rgb2gray(image_rgb)
# isolating the region of interest (ROI)
roi_region = slice(200, 1500) # you may need to adjust this
image_roi = image_gray[roi_region]
# binarizing the image by finding appropriate threshold
# you may need to play with kernel size, may be by taking 10 times bigger
kernel_size = (115, 115)
# you can also try other thresholding methods, including global threshold methods
threshold = filters.threshold_local(image_roi, kernel_size)
image_binary = image_roi < threshold
image_binary = segmentation.clear_border(image_binary)
# removing binary objects, which areas less than 100
min_area = 100 # you may need to play with this, in your example you put 1000
image_binary = morphology.remove_small_objects(image_binary, min_size=min_area)
# segmenting the objects
labels = measure.label(image_binary)
# puting back the segmentation into original image size frame
image_segmented = np.zeros(image_gray.shape, dtype=np.int32)
image_segmented[roi_region] = labels
plt.imshow(image_segmented)
输出将是这样的:
尾巴有点粗,希望大家可以调整一下方法,以获得更好的效果。
值得尝试的事情:模糊、可训练分割、直方图均衡、使用其他颜色空间(hsv、lab、xyz...)等。