如何在不丢失掩码中间数据的情况下去除边框上的噪声
How to remove the noise on the border without losing data in the middle of mask
我正在尝试从图像中分割出组织斑点。我做了一些初步的预处理并获得了以下结果。我担心的是边界上的噪音。如果我用 horizontal/vertical 内核腐蚀,我也会在中间丢失一些数据。我不确定什么是更好的结果,或者我应该通过不同的方法进行细分。
这是示例图片:
import numpy as np
import os
import matplotlib.pyplot as plt
from skimage import io
from skimage.filters import threshold_mean
from skimage.exposure import adjust_sigmoid, adjust_gamma
from skimage.morphology import opening
from skimage import morphology
import scipy.ndimage as ndi
def create_binary_mask(path_to_file):
file = io.imread(path_to_file)
#APPLY FILTERS FOR BETTER THRESHOLD
img_med = ndi.median_filter(file, size=20) #REDUCE NOISE
adjusted_gamma = adjust_gamma(img_med, 1.8, 2) #INCREASE GAMMA
adjusted_sigmoid = adjust_sigmoid(adjusted_gamma, 0.01) #INCREASE CONTRAST
#DO THE MEAN THRESHOLD
thresh = threshold_mean(adjusted_sigmoid)
binary = adjusted_sigmoid > thresh
#REMOVE SMALL NOISE WITHIN THE IMAGE
disk = morphology.disk(radius=7)
opening = morphology.binary_opening(binary, disk)
fig, axis = plt.subplots(1,4, figsize=(10,10))
axis[0].imshow(file, cmap='gray')
axis[0].set_title('Original File')
axis[1].imshow(adjusted_sigmoid, cmap='gray')
axis[1].set_title('Adjusted Sigmoid')
axis[2].imshow(binary, cmap='gray')
axis[2].set_title('Mean Threshold')
axis[3].imshow(opening, cmap='gray')
axis[3].set_title('After opening')
plt.savefig('results.png')
plt.show()
path_to_file = "sample_img.png"
create_binary_mask(path_to_file)
一种简单的方法是对二值图像执行形态学闭合,将噪声连接在一起形成单个轮廓。从这里我们可以找到轮廓并使用轮廓区域进行过滤。我们可以通过在轮廓中绘制来有效去除边框上的噪声。这是用背景颜色着色的噪声的结果。如果你想把它从面具上移除,你可以简单地用黑色 (0,0,0)
涂上它。
import cv2
import numpy as np
# Load image, grayscale, Gaussian blur, adaptive threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (7,7), 0)
thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,61,5)
# Morph close to connect noise
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,9))
close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=5)
# Filter using contour area and fill in contour to remove noise
cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
area = cv2.contourArea(c)
if area > 250000:
cv2.drawContours(image, [c], -1, (43,43,43), -1)
cv2.imwrite('image.png', image)
cv2.waitKey()
使用属性运算符(特别是 skimage.morphology.diameter_opening
)可能有助于删除长线,同时保持较小半径的对象不变。有关详细信息,请参阅此示例:
https://scikit-image.org/docs/dev/auto_examples/filters/plot_attribute_operators.html
您可以在此处找到该方法工作原理的详细解释:
https://scikit-image.org/docs/dev/auto_examples/developers/plot_max_tree.html
我正在尝试从图像中分割出组织斑点。我做了一些初步的预处理并获得了以下结果。我担心的是边界上的噪音。如果我用 horizontal/vertical 内核腐蚀,我也会在中间丢失一些数据。我不确定什么是更好的结果,或者我应该通过不同的方法进行细分。
这是示例图片:
import numpy as np
import os
import matplotlib.pyplot as plt
from skimage import io
from skimage.filters import threshold_mean
from skimage.exposure import adjust_sigmoid, adjust_gamma
from skimage.morphology import opening
from skimage import morphology
import scipy.ndimage as ndi
def create_binary_mask(path_to_file):
file = io.imread(path_to_file)
#APPLY FILTERS FOR BETTER THRESHOLD
img_med = ndi.median_filter(file, size=20) #REDUCE NOISE
adjusted_gamma = adjust_gamma(img_med, 1.8, 2) #INCREASE GAMMA
adjusted_sigmoid = adjust_sigmoid(adjusted_gamma, 0.01) #INCREASE CONTRAST
#DO THE MEAN THRESHOLD
thresh = threshold_mean(adjusted_sigmoid)
binary = adjusted_sigmoid > thresh
#REMOVE SMALL NOISE WITHIN THE IMAGE
disk = morphology.disk(radius=7)
opening = morphology.binary_opening(binary, disk)
fig, axis = plt.subplots(1,4, figsize=(10,10))
axis[0].imshow(file, cmap='gray')
axis[0].set_title('Original File')
axis[1].imshow(adjusted_sigmoid, cmap='gray')
axis[1].set_title('Adjusted Sigmoid')
axis[2].imshow(binary, cmap='gray')
axis[2].set_title('Mean Threshold')
axis[3].imshow(opening, cmap='gray')
axis[3].set_title('After opening')
plt.savefig('results.png')
plt.show()
path_to_file = "sample_img.png"
create_binary_mask(path_to_file)
一种简单的方法是对二值图像执行形态学闭合,将噪声连接在一起形成单个轮廓。从这里我们可以找到轮廓并使用轮廓区域进行过滤。我们可以通过在轮廓中绘制来有效去除边框上的噪声。这是用背景颜色着色的噪声的结果。如果你想把它从面具上移除,你可以简单地用黑色 (0,0,0)
涂上它。
import cv2
import numpy as np
# Load image, grayscale, Gaussian blur, adaptive threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (7,7), 0)
thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,61,5)
# Morph close to connect noise
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,9))
close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=5)
# Filter using contour area and fill in contour to remove noise
cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
area = cv2.contourArea(c)
if area > 250000:
cv2.drawContours(image, [c], -1, (43,43,43), -1)
cv2.imwrite('image.png', image)
cv2.waitKey()
使用属性运算符(特别是 skimage.morphology.diameter_opening
)可能有助于删除长线,同时保持较小半径的对象不变。有关详细信息,请参阅此示例:
https://scikit-image.org/docs/dev/auto_examples/filters/plot_attribute_operators.html
您可以在此处找到该方法工作原理的详细解释:
https://scikit-image.org/docs/dev/auto_examples/developers/plot_max_tree.html