一个简单的变换&一个复杂一点的变换
这一节接触了以下内容:
IplImage* cvCreateImage( CvSize size, int depth, int channels ):按照参数属性创建图像;
void cvSmooth( const CvArr* src, CvArr* dst,
int smoothtype=CV_GAUSSIAN,
int param1=3, int param2=0, double param3=0, double param4=0 ):平滑变换;
void cvPyrDown( const CvArr* src, CvArr* dst, int filter=CV_GAUSSIAN_5x5 ):缩小为原来的一半;
void cvPyrUp( const CvArr* src, CvArr* dst, int filter=CV_GAUSSIAN_5x5 ):扩大为原来的2倍;
void cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1, CvArr* dst2, CvArr* dst3 ):分割多通道数组成几个单通道数组或者从数组中提取一个通道(注:也可以用cvMerge函数来合并通道)
void cvCopy( const CvArr* src, CvArr* dst, const CvArr* mask=NULL ):可以实现IplImage结构图像间的相互拷贝,前提是结构属性要一致;
void cvCanny( const CvArr* image, CvArr* edges, double threshold1,
double threshold2, int aperture_size=3 ):采用 Canny 算法做边缘检测;
程序编写:
编程环境:windows xp系统; opencv 1.0; VC++6.0;
程序说明:
此程序实现了四个功能:
1、利用cvSmooth函数实现了图像的平滑操作;
2、利用cvPyrDown或者cvPyrUp函数实现了图片的向下或向上采样操作;
3、利用cvSplit函数实现了3通道图像分割成单通道图像的操作;
4、利用cvCanny函数实现了Canny算法的边缘检测。
加入头文件:
#include <cv.h> #include <highgui.h>
//平滑变换 void CLearningOpencvDlg::OnCvSmooth() { // TODO: Add your control notification handler code here cvNamedWindow("lovely_in", CV_WINDOW_AUTOSIZE); //创建图像窗口,第一个参数作为与其他函数交互的索引 cvShowImage("lovely_in", img_in); //把img图像显示在lovely的窗口中 cvNamedWindow("lovely_out", CV_WINDOW_AUTOSIZE); IplImage* img_out = cvCreateImage(cvGetSize(img_in), IPL_DEPTH_8U, 3); //开辟一个图像空间 cvSmooth(img_in, img_out, CV_GAUSSIAN, 3, 3); //进行opencv平滑运算 cvShowImage("lovely_out", img_out); cvWaitKey(0); //等待用户触发行为 cvReleaseImage(&img_out); cvDestroyWindow("lovely_in"); //销毁lovely窗口,同时释放为img的一个副本图像所开辟的内存,图像消失 cvDestroyWindow("lovely_out"); } //缩小变换 void CLearningOpencvDlg::OnImageSize() { // TODO: Add your control notification handler code here assert(img_in->width%2 == 0 && img_in->height%2 == 0); cvNamedWindow("lovely_in", CV_WINDOW_AUTOSIZE); //创建图像窗口,第一个参数作为与其他函数交互的索引 cvShowImage("lovely_in", img_in); //把img图像显示在lovely的窗口中 cvNamedWindow("lovely_out", CV_WINDOW_AUTOSIZE); IplImage* img_out = cvCreateImage(cvSize(img_in->width/2, img_in->height/2), img_in->depth, img_in->nChannels); //开辟一个图像空间 cvPyrDown(img_in, img_out); //图像缩小为原来的一半 // cvPyrUp(img_in, img_out); //图像放大2两倍(注:img_out开辟的空间是原来的两倍,否则程序异常) cvShowImage("lovely_out", img_out); cvWaitKey(0); //等待用户触发行为 cvReleaseImage(&img_out); cvDestroyWindow("lovely_in"); //销毁lovely窗口,同时释放为img的一个副本图像所开辟的内存,图像消失 cvDestroyWindow("lovely_out"); } //多通道变单通道 void CLearningOpencvDlg::OnChannels() { // TODO: Add your control notification handler code here IplImage *channel1, *channel2, *channel3; channel1 = cvCreateImage(cvGetSize(img_in), IPL_DEPTH_8U, 1); channel2 = cvCreateImage(cvGetSize(img_in), IPL_DEPTH_8U, 1); channel3 = cvCreateImage(cvGetSize(img_in), IPL_DEPTH_8U, 1); cvSplit(img_in, channel1, channel2, channel3, 0); cvCopy(channel3, SingleChannel, NULL); //复制副本 cvNamedWindow("channel1", CV_WINDOW_AUTOSIZE); cvNamedWindow("channel2", CV_WINDOW_AUTOSIZE); cvNamedWindow("channel3", CV_WINDOW_AUTOSIZE); cvShowImage("channel1", channel1); cvShowImage("channel2", channel2); cvShowImage("channel3", channel3); cvWaitKey(0); //等待用户触发行为 cvReleaseImage(&channel1); cvReleaseImage(&channel2); cvReleaseImage(&channel3); cvDestroyWindow("channel1"); //销毁lovely窗口,同时释放为img的一个副本图像所开辟的内存,图像消失 cvDestroyWindow("channel2"); cvDestroyWindow("channel3"); } //Canny变换 void CLearningOpencvDlg::OnCanny() { // TODO: Add your control notification handler code here if (!SingleChannel) { AfxMessageBox("请先进行通道图片转换"); return; } if (SingleChannel->nChannels !=1 ) { AfxMessageBox("图片不符合要求,必须为单通道灰色图片。"); return; } IplImage* out = cvCreateImage(cvGetSize(SingleChannel), IPL_DEPTH_8U, 1); cvCanny(SingleChannel, out, 120, 80, 3); cvNamedWindow("lovely", CV_WINDOW_AUTOSIZE); cvShowImage("lovely", out); cvWaitKey(0); cvReleaseImage(&out); cvDestroyWindow("lovely"); }
平滑操作:
图片采样效果图:
3通道变单通道效果图:
Canny算法边缘检测效果图: