简体   繁体   English

Python:图像预处理 - 对低对比度图像进行阈值化和二值化以进行斑点检测

[英]Python: Image preprocessing - Thresholding and binarizing low contrast images for Blob Detection

I am having difficulty thresholding and binarizing low contrast grayscale images that contain white blobs on a black background.我很难对包含黑色背景上的白色斑点的低对比度灰度图像进行阈值化和二值化。 Ultimately, I want to count and measure the area of all white blobs in the image.最终,我想计算和测量图像中所有白色斑点的面积。 However, Otsu's Thresholding method does not seem to be a good fit because my graylevel histogram lacks two clear peaks.但是,Otsu 的阈值方法似乎不太适合,因为我的灰度直方图缺少两个清晰的峰值。 Are there alternate thresholding methods that might be better suited to this type of image?是否有可能更适合此类图像的替代阈值方法?

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import skimage
import skimage.filters
from skimage.io import imread, imshow
from skimage.color import rgb2gray, rgb2hsv
from skimage.measure import label, regionprops, regionprops_table
from skimage.filters import threshold_otsu 
from scipy.ndimage import median_filter
from matplotlib.patches import Rectangle
from tqdm import tqdm

Here is my code:这是我的代码:

pic = imread('image.jpg')
imshow(pic)

raw grayscale image:原始灰度图像:

原始灰度图像

# blur the image to de-noise

blurred_image = skimage.filters.gaussian(pic, sigma=1.0)

# show the histogram of the blurred image

histogram, bin_edges = np.histogram(blurred_image, bins=256, range=(0.0, 1.0))
fig, ax = plt.subplots()
plt.plot(bin_edges[0:-1], histogram)
plt.title("Graylevel histogram")
plt.xlabel("gray value")
plt.ylabel("pixel count")
plt.xlim(0, 1.0)
plt.show()

graylevel histogram:灰度直方图:

灰度直方图

# perform automatic thresholding

t = skimage.filters.threshold_otsu(blurred_image)
print("Found automatic threshold t = {}.".format(t))

Found automatic threshold t = 0.035040431336474526.发现自动阈值 t = 0.035040431336474526。

# create a binary mask with the threshold found by Otsu's method

binary_mask = blurred_image > t

fig, ax = plt.subplots()
plt.imshow(binary_mask, cmap="gray")
plt.show()

binary mask:二进制掩码:

二进制掩码

The white halo in the center of the image is quite problematic.图像中心的白色光晕非常有问题。 Is there a way to de-noise, threshold, and binarize such that I can isolate the white blobs in the image?有没有办法去噪、阈值和二值化,以便我可以隔离图像中的白色斑点?

Given your image, the blobs are the outliers.鉴于您的图像,斑点是异常值。

From the given grayscale image gray , here are some measures:从给定的灰度图像gray ,这里有一些措施:

np.max(gray)

89 89

np.mean(gray)

7.49876 7.49876

np.median(gray)

6.0 6.0

Although the mean and median are in the range of 6 to 8, the maximum value is at 89, meaning there are some bright pixels in there.虽然平均值和中位数在 6 到 8 的范围内,但最大值为 89,这意味着那里有一些明亮的像素。 To get these outliers, I placed the threshold at mean + ( x * standard_deviation) The value x is a value of your choice given the outliers present.为了获得这些异常值,我将阈值设置为均值 + ( x * standard_deviation)x是您在存在异常值的情况下选择的值。 For this image, I chose x = 3对于这张图片,我选择了x = 3

Code using OpenCV :使用 OpenCV 的代码

# read image in color BGR
img =cv2.imread('Pattern.jpg')
# convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# binarize using threshold
thresh = cv2.threshold(gray, int(np.mean(gray) + (np.std(gray) * 3)), 255, cv2.THRESH_BINARY)

The threshold value: thresh[0] -> 31.0阈值: thresh[0] -> 31.0

Pixels above this value are white:高于此值的像素为白色:

cv2.imshow('output', thresh[1])

在此处输入图像描述

You can try changing the x value for a better output or run a median filter on the above result您可以尝试更改x值以获得更好的输出或对上述结果运行中值滤波器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM