Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Image processing 如何从直方图中获取阈值?_Image Processing_Opencv_Computer Vision - Fatal编程技术网

Image processing 如何从直方图中获取阈值?

Image processing 如何从直方图中获取阈值?,image-processing,opencv,computer-vision,Image Processing,Opencv,Computer Vision,我正在OpenCV中编写一个Android应用程序来检测斑点。一项任务是对图像设置阈值,以区分前景对象和背景(参见图) 只要图像已知,它就可以正常工作,我可以手动将阈值传递给threshold()——在这个特定的图像中,比如200。但是假设图像不是已知的,只知道会有暗的固体背景和较亮的前景对象,我如何动态地计算出阈值呢 我遇到了直方图,在这里我可以计算灰度图像的强度分布。但是我找不到一种方法来分析直方图并选择感兴趣的对象(较轻的)所在的值。就是,;我想区分明显较暗的背景尖峰和较亮的前景尖峰——在

我正在OpenCV中编写一个Android应用程序来检测斑点。一项任务是对图像设置阈值,以区分前景对象和背景(参见图)

只要图像已知,它就可以正常工作,我可以手动将阈值传递给threshold()——在这个特定的图像中,比如200。但是假设图像不是已知的,只知道会有暗的固体背景和较亮的前景对象,我如何动态地计算出阈值呢

我遇到了直方图,在这里我可以计算灰度图像的强度分布。但是我找不到一种方法来分析直方图并选择感兴趣的对象(较轻的)所在的值。就是,;我想区分明显较暗的背景尖峰和较亮的前景尖峰——在本例中是200以上,但在另一种情况下,如果对象是灰色的,则可以是100


如果你说背景是暗的(黑色),前景是浅的,那么我建议使用(或任何其他YXXYCrCb等),因为这样的颜色空间的第一个组成部分是亮度(或闪电

因此,在提取Y通道后(通过
extractChennel
函数),我们需要分析该通道的直方图(图像):

看到第一个(左)驼峰了吗?它代表图像上的黑暗区域(你的处境中的背景)。所以我们现在的目标是找到一个包含这个驼峰的部分(在横坐标上,它是图像中的红色部分)。很明显,这段的左边点是零。右点是第一点,其中:

  • 直方图的(局部)最大值从点的左侧开始
  • 直方图的值小于一些小ε(您可以将其设置为10)
我画了一条绿色的垂直线来显示这个柱状图中线段右点的位置

就这样!该段的右侧点是所需的阈值。结果如下(ε为10,计算的阈值为50):


我认为删除上面图像中的噪声对您来说不是问题。

如果您所有的图像都是这样的,或者可以采用这种风格,我认为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以上的阈值也是可以接受的。。。