python+opencv 灰度直方图及其二值化

图像直方图(histogram)是图像的统计学特征,常用于了解图像的基本特征以便分析。不过图像的直方图不具有空间特征。

图像的灰度直方图(histogram),就是将图像转化成灰度图像之后,统计各个像素点的灰度值,绘制成直方图,其横轴是灰度值(0,255),纵轴是该灰度值所对应的像素的数目。对灰度直方图做积分=图像的size。

灰度直方图

1 def plt_hist(img):
2     plt.hist(img.ravel(), 256, [0, 256])
3     plt.show()

三色折线图(可以直观的看出三原色的占比分布)

1 def img_hist(img):
2     color = ("blue", "green", "red")
3     for i, color in enumerate(color):
4         hist = cv.calcHist([img], [i], None, [256], [0, 256])
5         plt.plot(hist, color=color)
6         plt.xlim([0, 25])
7     plt.show()

一般来说,直方图有双峰性,会有两个峰值以区分前景和背景,但并不是每张图像都如此。分析图像的变化,进而确定最优二值化值。在两个峰值之间的最小值,经常是我们需要找的二值化值。我们可以发现,两个峰值之间的波谷是两个峰值的叠加区。有了灰度直方图,我们可以给图片做二值化。确定哪些pixel是我们需要关注的哪些是不重要的。二值化有两种主要形式:一种是全局阈值二值化,另外一种是局部阈值二值化。

选择二值化的值(找到两个双峰的最低点,但不是都有多峰可能存在多个最小值,可以用局部阈值)

经典算法:isodata algorithm 预设初始的二值化值,然后不断迭代,效果不是最好的

     Otsu algorithm 研究双峰的关联性求二值化值

     Entropy algorithm 熵算法,前景熵hb和背景熵hw。0-255个灰度值分别求熵,最大的h值就是我们要找的二值化值。

其他算法:triangle algorithm 灰度值的最大值和最左侧的最小值连接,然后做垂线,当垂线距离最大时,所对应的灰度值就是我们需要的二值化值,不过这个算法效果不是很好,应用于细胞分离比较多。

使用opencvAPI:(otsu和triangle)

 1 def threshold_binary(src):
 2     #把BGR图像转化成灰度图像
 3     gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
 4     #获得灰度直方图以便调整算法的使用
 5     plt.hist(src.ravel(), 256, [0, 256])
 6     plt.show()
 7     #几种二值化方法
 8     ret, binary = cv.threshold(gray, 50, 255, cv.THRESH_BINARY)#指定阈值50
 9     print("二值阈值: %s" % ret)
10     cv.imshow("threshold_binary", binary)
11     ret_otsu, binary_otsu = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
12     print("二值阈值_otsu: %s" %ret_otsu)
13     cv.imshow("threshold_binary_otsu", binary_otsu)
14     ret_tri, binary_tri = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_TRIANGLE)
15     print("二值阈值_tri: %s" % ret_tri)

运行示例:

二值阈值: 50.0
二值阈值_otsu: 173.0
二值阈值_tri: 250.0

以上是全局阈值二值化的结果,下面还有局部阈值二值化。个人觉得局部阈值更好的描绘了图片的轮廓。

1 def local_threshold_binary(src):
2     gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
3     binary_mean = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 25, 10)
4     cv.imshow("binary_mean", binary_mean)5
6     binary_gau = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 25, 10)
7     cv.imshow("binary_gau", binary_gau)

两种方法,

超大图像及其二值化

经常会遇到一些比较大的图像,我们可以把图片拆分成很多个小方块分别进行全局二值化或者使用局部阈值。这时候可以用opencv处理图像显示不全,需要把图片保存到本地才行。

 1 def big_image_binary(src):
 2     print(src.shape)
 3     cw = 256
 4     ch = 256
 5     h, w, c = src.shape
 6     gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
 7     for row in range(0, h, ch):
 8         for col in range(0, w, cw):
 9             roi = gray[row:row+ch, col:col+cw]
10             dst = cv.adaptiveThreshold(roi, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 25, 10)
11            # ret_otsu, dst = cv.threshold(roi, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
12             gray[row:row+ch, col:col+cw] = dst
13             #计算方差和平均值,当这两个数值小于某一值时,可以认为图像为空白,做空白图像过滤
14             print(np.std(dst), np.mean(dst))
15     cv.imwrite("E:/photo/big_img_binary.jpg", gray)

                   

原文地址:https://www.cnblogs.com/lzying/p/11368294.html

时间: 2024-07-29 13:14:15

python+opencv 灰度直方图及其二值化的相关文章

【OPENCV】图像的预处理(灰度图、二值化、字符矫正(旋转))

1.首先加载原始图片: 2.cvCvtColor(img, source, CV_BGR2GRAY);转化成灰度图像: 3.cvThreshold(source,source_gray,100,255,CV_THRESH_BINARY );进行二值化处理. 由于原始的图片会有一定的角度,需要进行旋转,而旋转的话可以使用OPENCV提供的函数实现,本文中采用的是自己编写的,即通过旋转360,并记录旋转某个角度的时候使得在x轴方向的投影最大化. 如图,经过处理的图片效果如下所示: 完整的工程已经上传

3直方图与二值化,图像梯度

1直方图 #直方图--增强对比度 def equalHist_demo(image): gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY) dst = cv.equalizeHist(gray) cv.imshow("equalHist_demo", dst) def clahe_demo(image): gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY) clahe = cv.createCLAHE(clip

【opencv】统计图像二值化后白色像素点个数

应用:图像特征提取 #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/core/core.hpp" #include <opencv\ml.h> #include <iostream> #include "cv.h" #include "highgui.

c#图像灰度化、灰度反转、二值化

图像灰度化:将彩色图像转化成为灰度图像的过程成为图像的灰度化处理.彩色图像中的每个像素的颜色有R.G.B三个分量决定,而每个分量有255中值可取,这样一个像素点可以有1600多万(255*255*255)的颜色的变化范围.而灰度图像是R.G.B三个分量相同的一种特殊的彩色图像,其一个像素点的变化范围为255种,所以在数字图像处理种一般先将各种格式的图像转变成灰度图像以使后续的图像的计算量变得少一些.灰度图像的描述与彩色图像一样仍然反映了整幅图像的整体和局部的色度和亮度等级的分布和特征.图像的灰度

《opencv学习》 之 二值化

主要讲解OTSU算法实现图像二值化:    1.统计灰度级图像中每个像素值的个数. 2.计算第一步个数占整个图像的比例. 3.计算每个阈值[0-255]条件下,背景和前景所包含像素值总个数和总概率(就是分别计算背景和前景下第一步和第二步的              和). 4.比较第三步前景和背景之间方差,找到最大的一个确定为选定的阈值. OTSU源码: 1 #include <opencv2/opencv.hpp> 2 #include <iostream> 3 #include

图像 - 灰度化、灰度反转、二值化

原文地址:http://www.cnblogs.com/gdjlc/archive/2013/03/05/2943801.html 图像灰度化: 将彩色图像转化成为灰度图像的过程成为图像的灰度化处理.彩色图像中的每个像素的颜色有R.G.B三个分量决定,而每个分量有255中值可取,这样一个像素点可以有1600多万(255*255*255)的颜色的变化范围.而灰度图像是R.G.B三个分量相同的一种特殊的彩色图像,其一个像素点的变化范围为255种,所以在数字图像处理种一般先将各种格式的图像转变成灰度图

数学思想方法-python计算战(8)-机器视觉-二值化

二值化 hreshold Applies a fixed-level threshold to each array element. C++: double threshold(InputArray src, OutputArray dst, double thresh, doublemaxval, int type) Python: cv2.threshold(src, thresh, maxval, type[, dst]) → retval, dsthighlight=cvthresho

【OpenCV教程之九】平滑/模糊图片 Smooth / Blur Images及 彩色图转 灰度图和二值化

这一节,谈一谈如何对图像进行平滑,也可以叫做模糊.平滑图像的主要目的是减少噪声,这样采用平滑图像来降低噪声是是非常常见的预处理方法. 1.归一化滤波平滑-Homogeneous Smoothing 2.高斯滤波平滑-Gaussian Smoothing 3.中值滤波平滑-Median Smoothing 4.双边滤波平滑-Bilateral Smoothing 平滑是通过滑动窗口(内核或过滤器)扫描整个图像窗口,计算每个像素的基于核的值的和重叠的原始图像的像素的值的值来完成.这个过程在数学上称为

十三种基于直方图的图像全局二值化算法原理、实现、代码及效果(转)

十三种基于直方图的图像全局二值化算法原理.实现.代码及效果(转) http://www.cnblogs.com/carekee/articles/3643394.html 图像二值化的目的是最大限度的将图象中感兴趣的部分保留下来,在很多情况下,也是进行图像分析.特征提取与模式识别之前的必要的图像预处理过程.这个看似简单的问题,在过去的四十年里受到国内外学者的广泛关注,产生了数以百计的阈值选取方法,但如同其他图像分割算法一样,没有一个现有方法对各种各样的图像都能得到令人满意的结果. 在这些庞大的分