OpenCv学习篇——图像阈值化算法
一.阈值化算法定义
所谓二值化简单一点讲,就是将图像划分成黑和白,通过设定一个标准如果大于这个标准就设为白,如果小于这个标准,就设为黑,而这个标准,就叫做阈值。
二.算法原理
1.RGB图像转灰度图像原理:RGB图像是有3个通道,也就是一个3维的矩阵,而灰度图,大家都知道只有一个通道,那么如何将一个3通道的事物转为1通道的事物呢?其实这其中是有一个转换公式的:
Gray = R*0.299 + G*0.587 + B*0.114
2.阈值化原理
三.代码中用到的OpenCv中的库函数详细解答(OpenCv2.49版本)
1>这些头文件包含二值化算法中的库函数
#include ‘’opencv2\highgui\highgui.hpp‘’
#include ‘’opencv2\core\core.hpp‘’
#include ‘’opencv2\imgproc\imgproc.hpp‘’
#include ‘’opencv2/opencv.hpp‘’
2>程序开头有这样
#include #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
这句话是为了屏蔽控制台程序,每次运行都会出现一个类似dos似的黑框框为了美观,选择把它给屏蔽了,不屏蔽也不影响功能的使用。
3>加载一幅图像:IplImage *pSrcImage = cvLoadImage("lxy.jpg", CV_LOAD_IMAGE_UNCHANGED);
第一个参数是文件名,存在本工程中的文件夹即可
第二个参数:
第一个参数:cvGetSize(pSrcImage)函数得到图像的尺寸,pSrcImage为加载之前原图的指针变量
第二个参数:
图像像素的位深度,值为可以为下面一种:
(
IPL_DEPTH_8S - 8位符号整数
IPL_DEPTH_16U - 16位无符号整数
IPL_DEPTH_16S - 16位符号整数
IPL_DEPTH_32S - 32位符号整数
IPL_DEPTH_32F - 单精度浮点数
第三个参数为通道数
cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);窗口名字自动适应尺寸
cvShowImage(pstrWindowsSrcTitle, pSrcImage);//指向原图的指针
普通函数与回调函数的区别:
对普通函数的调用:
调用程序发出对普通函数的调用后,程序执行立即转向被调用函数执行,直到被调用函数执行完毕后,再返回调用程序继续执行。从发出调用的程序的角度看,这个过程为“调用-->等待被调用函数执行完毕-->继续执行”
对回调函数调用:
调用程序发出对回调函数的调用后,不等函数执行完毕,立即返回并继续执行。这样,调用程序执和被调用函数同时在执行。当被调函数执行完毕后,被调函数会反过来调用某个事先指定函数,以通知调用程序:函数调用结束。这个过程称为回调(Callback),这正是回调函数名称的由来。
8>转为二值图像。
cvThreshold(g_pGrayImage, g_pBinaryImage, pos, 255, CV_THRESH_BINARY);
//第一个参数表示输入图像,必须为单通道灰度图。
//第二个参数表示输出的边缘图像,为单通道黑白图。
//第三个参数表示阈值
//第四个参数表示最大值。
//第五个参数表示运算方法
CV_THRESH_BINARY =0,
CV_THRESH_BINARY_INV =1,
CV_THRESH_TRUNC =2,
CV_THRESH_TOZERO =3,
CV_THRESH_TOZERO_INV =4,
CV_THRESH_MASK =7,
CV_THRESH_OTSU =8
四.程序流程图
五.程序源码
#include ‘’opencv2\highgui\highgui.hpp‘’#include ‘’opencv2\core\core.hpp‘’
#include ‘’opencv2\imgproc\imgproc.hpp‘’
#include ‘’opencv2/opencv.hpp‘’
using namespace std;
using namespace cv;
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") //屏蔽控制台程序
IplImage *g_pGrayImage = NULL;
IplImage *g_pBinaryImage = NULL;
const char *pstrWindowsBinaryTitle = "二值图(fzhykx1995)";
void on_trackbar(int pos)
{
// 转为二值图函数
cvThreshold(g_pGrayImage, g_pBinaryImage, pos, 255, CV_THRESH_BINARY);
//第一个参数表示输入图像,必须为单通道灰度图。
//第二个参数表示输出的边缘图像,为单通道黑白图。
//第三个参数表示阈值
//第四个参数表示最大值。
//第五个参数表示运算方法
// 显示二值图
cvShowImage(pstrWindowsBinaryTitle, g_pBinaryImage);//第一个参数决定确定在哪个存在的窗口中显示图像,第二个参数是IplImage类型指针确定要显示的图像。
}
int main(int argc, char** argv)
{
const char *pstrWindowsSrcTitle = "原图(fzhykx1995)";
const char *pstrWindowsToolBarName = "二值图阈值";
// 从文件中加载原图
IplImage *pSrcImage = cvLoadImage("lxy.jpg", CV_LOAD_IMAGE_UNCHANGED); //第一个参数是文件名,第二个参数是
// 转为灰度图
g_pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);
//cvGetSize()函数得到图像大小
//depth
//图像像素的位深度,值为可以为下面一种:
//IPL_DEPTH_8U - 8位无符号整数
//IPL_DEPTH_8S - 8位符号整数
//IPL_DEPTH_16U - 16位无符号整数
//IPL_DEPTH_16S - 16位符号整数
//IPL_DEPTH_32S - 32位符号整数
//IPL_DEPTH_32F - 单精度浮点数
//IPL_DEPTH_64F - 双精度浮点数
//channel
//IplImage* cvCreateImage(CvSize cvSize(int width, int height), int depth, int channels);
//channel:通道数 RGB的时候是3 灰度图的时候1
cvCvtColor(pSrcImage, g_pGrayImage, CV_BGR2GRAY);//CV_BGR2GRAY是RGB到gray。第一个参数的源图像第二个参数是目标图像
// 创建二值图
g_pBinaryImage = cvCreateImage(cvGetSize(g_pGrayImage), IPL_DEPTH_8U, 1);
// 显示原图
cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);//窗口名字自动适应尺寸
cvShowImage(pstrWindowsSrcTitle, pSrcImage);//指向原图
// 创建二值图窗口
cvNamedWindow(pstrWindowsBinaryTitle, CV_WINDOW_AUTOSIZE);
// 滑动条
int nThreshold = 0;
cvCreateTrackbar(pstrWindowsToolBarName, pstrWindowsBinaryTitle, &nThreshold, 254, on_trackbar);
on_trackbar(1);
cvWaitKey(0);
cvDestroyWindow(pstrWindowsSrcTitle);
cvDestroyWindow(pstrWindowsBinaryTitle);
cvReleaseImage(&pSrcImage);
cvReleaseImage(&g_pGrayImage);
cvReleaseImage(&g_pBinaryImage);
return 0;
}