图像的二值化是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果。
将256个亮度等级的灰度图像通过适当的阀值选取而获得仍然可以反映图像整体和局部特征的二值化图像。在数字图像处理中,二值图像占有非常重要的地位,首先,图像的二值化有利于图像的进一步处理,使图像变得简单,而且数据量减小,能凸显出感兴趣的目标的轮廓。其次,要进行二值图像的处理与分析,首先要把灰度图像二值化,得到二值化图像。
所有灰度大于或等于阀值的像素被判定为属于特定物体,其灰度值为255表示,否则这些像素点被排除在物体区域以外,灰度值为0,表示背景或者例外的物体区域
二值化的公式如下:
灰度图grayscale
灰度是指只含亮度信息,不含色彩信息的图像。黑白照片就是灰度图,特点是亮度由暗到明,变化是连续的。要表## 标题示灰度图,就需要把亮度值进行量化
使用灰度图的好处:
① RGB的值都一样。
② 图像数据即调色板索引值,就是实际的RGB值,也就是亮度值。
③ 因为是256色调色板,所以图像数据中一个字节代表一个像素,很整齐。
所以,做图像处理时都采用灰度图。
将一幅RGB格式的图像转化为灰度图
二值化图像代码如下:
//对一幅图像进行二值化
#include <iostream>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\core\core.hpp>
#include <opencv2\imgproc\imgproc.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat imag, result;
//imag = imread("C://1.bmp"); //不进行灰度处理,如果原图是彩色的,二值化处理后也会有一点颜色在图像上!
imag = imread("C://1.bmp",0); //将读入的彩色图像直接以灰度图像读入 不加0的话不是灰度图像!
namedWindow("原图", 1); //灰度图像
imshow("原图", imag);
result = imag.clone();
//进行二值化处理,选择30,200.0为阈值 设置为 30 300时候 更加的明亮!
threshold(imag, result, 30, 200.0, CV_THRESH_BINARY);
namedWindow("二值化图像");
imshow("二值化图像", result);
waitKey();
return 0;
}
一般先将图像灰度化,然后再二值化,然后在进行边缘处理等操作。。。
灰度化–>二值化—>边缘提取>>>
测试结果如下:
30 200 阀值
30 300阀值 发现更加的明亮了!
换一张彩色的照片进行测试:
转化为灰度图像如下
二值化的图像如下:
如果一开始这样设置:
imag = imread("C://1.bmp"); //不进行灰度处理,如果原图是彩色的,二值化处理后也会有一点颜色在图像上!
测试的结果为:
最后再说一点注意事项:
cvThreshold是opencv库中的一个函数。作用:函数 cvThreshold 对单通道数组应用固定阈值操作。该函数的典型应用是对灰度图像进行阈值操作得到二值图像。(cvCmpS 也可以达到此目的) 或者是去掉噪声,例如过滤很小或很大象素值的图像点。本函数支持的对图像取阈值的方法由 threshold_type 确定。
形式:void cvThreshold( const CvArr* src, CvArr* dst, double threshold, double max_value, int threshold_type );
src:原始数组 (单通道 , 8-bit of 32-bit 浮点数)。
dst:输出数组,必须与 src 的类型一致,或者为 8-bit。
threshold:阈值
max_value:使用 CV_THRESH_BINARY 和 CV_THRESH_BINARY_INV 的最大值。
threshold_type:阈值类型 threshold_type=CV_THRESH_BINARY:
如果 src(x,y)>=threshold ,dst(x,y) = max_value; 否则,des(x,y)=0;
threshold_type=CV_THRESH_BINARY_INV:
如果 src(x,y)<threshold,dst(x,y) = 0; 否则,dst(x,y) = max_value.
文章开头有个公式!对应!
在这里一定要注意dst必须是单通道的图像,本人之前写成3通道图像,一直出错,检查了好久才发现问题所在。这说明还是要细心。