Image processing 如何从直方图中获取阈值?
我正在OpenCV中编写一个Android应用程序来检测斑点。一项任务是对图像设置阈值,以区分前景对象和背景(参见图) 只要图像已知,它就可以正常工作,我可以手动将阈值传递给threshold()——在这个特定的图像中,比如200。但是假设图像不是已知的,只知道会有暗的固体背景和较亮的前景对象,我如何动态地计算出阈值呢 我遇到了直方图,在这里我可以计算灰度图像的强度分布。但是我找不到一种方法来分析直方图并选择感兴趣的对象(较轻的)所在的值。就是,;我想区分明显较暗的背景尖峰和较亮的前景尖峰——在本例中是200以上,但在另一种情况下,如果对象是灰色的,则可以是100Image processing 如何从直方图中获取阈值?,image-processing,opencv,computer-vision,Image Processing,Opencv,Computer Vision,我正在OpenCV中编写一个Android应用程序来检测斑点。一项任务是对图像设置阈值,以区分前景对象和背景(参见图) 只要图像已知,它就可以正常工作,我可以手动将阈值传递给threshold()——在这个特定的图像中,比如200。但是假设图像不是已知的,只知道会有暗的固体背景和较亮的前景对象,我如何动态地计算出阈值呢 我遇到了直方图,在这里我可以计算灰度图像的强度分布。但是我找不到一种方法来分析直方图并选择感兴趣的对象(较轻的)所在的值。就是,;我想区分明显较暗的背景尖峰和较亮的前景尖峰——在
如果你说背景是暗的(黑色),前景是浅的,那么我建议使用(或任何其他YXX如YCrCb等),因为这样的颜色空间的第一个组成部分是亮度(或闪电) 因此,在提取Y通道后(通过
extractChennel
函数),我们需要分析该通道的直方图(图像):
看到第一个(左)驼峰了吗?它代表图像上的黑暗区域(你的处境中的背景)。所以我们现在的目标是找到一个包含这个驼峰的部分(在横坐标上,它是图像中的红色部分)。很明显,这段的左边点是零。右点是第一点,其中:
- 直方图的(局部)最大值从点的左侧开始
- 直方图的值小于一些小ε(您可以将其设置为10)
我认为删除上面图像中的噪声对您来说不是问题。如果您所有的图像都是这样的,或者可以采用这种风格,我认为cv2.THRESHOLD_OTSU,即OTSU的tresholding算法是一个很好的选择 以下是在命令终端中使用Python的示例:
>>> import cv2
>>> import numpy as np
>>> img2 = cv2.imread('D:\Abid_Rahman_K\work_space\sofeggs.jpg',0)
>>> ret,thresh = cv2.threshold(img2,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
>>> ret
122.0
ret
是自动计算的阈值。我们只传递“0”作为此的阈值
我在GIMP中得到124(这与我们得到的结果相当)。而且它还能消除噪音。见下面的结果:
< /P> < P>以下是Abid的回答的C++实现,它与OpenCV 3。X:
// Convert the source image to a 1 channel grayscale:
Mat gray;
cvtColor(src, gray, CV_BGR2GRAY);
// Apply the threshold function with the CV_THRESH_OTSU setting as well
// You can skip having it return the value, but I include it for showing the
// results from OTSU
double thresholdValue = threshold(gray, gray, 0, 255, CV_THRESH_BINARY+CV_THRESH_OTSU);
// Present the threshold value
printf("Threshold value: %f\n", thresholdValue);
对原始图像运行此操作,我得到以下结果:
OpenCV计算出的阈值为122,接近于阿比德在答案中找到的值
为了验证,我更改了原始图像,如图所示:
并生成以下值,新阈值为178:
有很多方法可以做到这一点。也许大津的方法对你有用。如果不是,这仍然是一个很好的起点。你能上传100阈值的图像吗?因为在图像上50以上的阈值也是可以接受的。。。