您的位置:首页 > 运维架构

opencv入门学习之四: 灰度图像的二值化

2017-03-22 10:05 621 查看
博客用于知识记录和学习交流,欢迎大家互动学习。

作者:JackGao24 博客园文章链接:

作者:JackGao16 CSDN文章链接:http://blog.csdn.net/u013108511/article/details/64905256

邮箱:gshuai16@mail.ustc.edu.cn

1、图像二值化的原理

图像的二值化就是将图像上的的像素点的灰度值与设定的阈值进行比较,绕后将像素点的灰度值设置为0或者255,也就将整个图象显示出最明显的黑白效果。

灰度处理后就能够二值化了,图像的二值化是方便出翔处理的重要步骤,不适合对颜色有要求的图像进行处理,而对轮廓有要求的图像处理比较有效。

2、图像二值化中的数据结构和函数

2.1、关于IplLmage

IplImage是OpenCV中CxCore部分基础的数据结构,用来表示图像,其中Ipl是Intel Image Processing Library的简写。

IplImage的结构定义如下:

typedef struct _IplImage
{
int  nSize;         /* IplImage大小 */
int  ID;            /* 版本 (=0)*/
int  nChannels;     /* 大多数OPENCV函数支持1,2,3 或 4 个通道 */
int  alphaChannel;  /* 被OpenCV忽略 */
int  depth;         /* 像素的位深度: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,
IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F 可支持 */
char colorModel[4]; /* 被OpenCV忽略 */
char channelSeq[4]; /* 同上 */
int  dataOrder;     /* 0 - 交叉存取颜色通道, 1 - 分开的颜色通道.
cvCreateImage只能创建交叉存取图像 */
int  origin;        /* 0 - 顶—左结构,
1 - 底—左结构 (Windows bitmaps 风格) */
int  align;         /* 图像行排列 (4 or 8). OpenCV 忽略它,使用 widthStep 代替 */
int  width;         /* 图像宽像素数 */
int  height;        /* 图像高像素数*/
struct _IplROI *roi;/* 图像感兴趣区域. 当该值非空只对该区域进行处理 */
struct _IplImage *maskROI; /* 在 OpenCV中必须置NULL */
void  *imageId;     /* 同上*/
struct _IplTileInfo *tileInfo; /*同上*/
int  imageSize;     /* 图像数据大小(在交叉存取格式下imageSize=image->height*image->widthStep),单位字节*/
char *imageData;  /* 指向排列的图像数据 */
int  widthStep;   /* 排列的图像行大小,以字节为单位 */
int  BorderMode[4]; /* 边际结束模式, 被OpenCV忽略 */
int  BorderConst[4]; /* 同上 */
char *imageDataOrigin; /* 指针指向一个不同的图像数据结构(不是必须排列的),是为了纠正图像内存分配准备的 */
}
IplImage;


2.2、关于cvCvtColor

cvCvtColor(…),是Opencv里的颜色空间转换函数,可以实现BGR颜色向HSV,HSI等颜色空间的转换,也可以转换为灰度图像。

void cvCvtColor( const CvArr* src, CvArr* dst, int code );


src:

输入的 8-bit,16-bit或 32-bit单倍精度浮点数影像。

dst:

输出的8-bit, 16-bit或 32-bit单倍精度浮点数影像。

code:

色彩空间转换的模式,该code来实现不同类型的颜色空间转换。比如CV_BGR2GRAY表示转换为灰度图,CV_BGR2HSV将图片从RGB空间转换为HSV空间。其中当code选用CV_BGR2GRAY时,dst需要是单通道图片。当code选用CV_BGR2HSV时,对于8位图,需要将RGB值归一化到0-1之间。这样得到HSV图中的H范围才是0-360,S和V的范围是0-1。

3、参考源代码和结果输出

读入彩色图像,转化为灰度图像,在进行二值化处理:

//灰度图像的二值化
#include <opencv2/opencv.hpp>
using namespace cv;

IplImage *g_pGrayImage = NULL;  //创建一个灰度图像
IplImage *g_pBinaryImage = NULL;  //创建一个二值化图像
const char *pstrWindowsBinaryTitle = "二值图";  //窗口名

void on_trackbar(int pos)
{
// 转为二值图
cvThreshold(g_pGrayImage, g_pBinaryImage, pos, 255, CV_THRESH_BINARY);//CV_THRESH_BINARY=0 value=value>threshold?max_value:0
// 显示二值图
cvShowImage(pstrWindowsBinaryTitle, g_pBinaryImage);
}

int main( int argc, char** argv )
{
const char *pstrWindowsSrcTitle = "原图";  //显示原图像的窗口名
const char *pstrWindowsGrayTitle = "灰度图像";//显示灰度图像的窗口名
const char *pstrWindowsToolBarName = "二值图阈值";  //工具条名称

// 从文件中加载原图
IplImage *pSrcImage = cvLoadImage("pic.jpg", CV_LOAD_IMAGE_ANYCOLOR);

// 转为灰度图
g_pGrayImage =  cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);
//CV_BGR2GRAY:BGR to GRAY
cvCvtColor(pSrcImage, g_pGrayImage, CV_BGR2GRAY);

// 创建二值图
g_pBinaryImage = cvCreateImage(cvGetSize(g_pGrayImage), IPL_DEPTH_8U, 1);

// 显示原图
cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);
cvShowImage(pstrWindowsSrcTitle, pSrcImage);

// 显示灰度原图
cvNamedWindow(pstrWindowsGrayTitle, CV_WINDOW_AUTOSIZE);
cvShowImage(pstrWindowsGrayTitle, g_pGrayImage);

// 创建二值图窗口
cvNamedWindow(pstrWindowsBinaryTitle, CV_WINDOW_AUTOSIZE);

// 滑动条
int nThreshold = 40;
cvCreateTrackbar(pstrWindowsToolBarName, pstrWindowsBinaryTitle, &nThreshold, 255, on_trackbar);

on_trackbar(0);

cvWaitKey(0);

cvDestroyWindow(pstrWindowsSrcTitle);
cvDestroyWindow(pstrWindowsBinaryTitle);
cvReleaseImage(&pSrcImage);
cvReleaseImage(&g_pGrayImage);
cvReleaseImage(&g_pBinaryImage);
return 0;
}


输出的结果为:



后续图像处理还有更新,希望大家可以留言讨论相互学习。

我是Jack,学无止境。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: