接触到图像处理,不免要用到OpenCV,丰富的图像处理函数,不仅在追求高性能(基于C实现)上而且开源库更是方便开发者不断扩展openCV库。是计算机视觉研究方向的必要开发工具。由于刚刚接触OpenCV,本文主要是是对于OpenCV一些简单实例的测试与实现。
对于OpenCV的安装网上很多帖子,这里就不用过多介绍了,做几点说明。(参考:http://blog.csdn.net/poem_qianmo/article/details/19809337 和 http://blog.csdn.net/morewindows/article/details/8225783)
I:注意VS版本与OpenCV的版本,有些OpenCV只包含VC14,就只能和VS2015配合使用.
II:VS添加项目注意选择win32还是X64,本人系统是64位的,运行Win32会报错
III:包含库文件的时候注意是Debug还是Release,debug版的lib带d的.
IV:配置环境变量后注意重启电脑,重启,之前以为不用重启,但是无法是配置生效,所以还是乖乖重启吧。
//第一个例子:显示图像
void showImage(){
//IplImage 结构体
IplImage *img = cvLoadImage("1234.jpg");//lena.tif
if (img == NULL){
cout << "Load File Failed.\n";
return;
}
//创建一个窗口,如果值设置为0.用户可以调整窗口的大小。 CV_WINDOW_AUTOSIZE = 1,窗口自适应图片大小,无法调整窗口
cvNamedWindow("Origin Image", CV_WINDOW_AUTOSIZE);
cvShowImage("Origin Image", img);
//设置时间,单位为ms.如果函数参数为0,则一直等待用户按键
cvWaitKey(0);
cvReleaseImage(&img);
//关闭窗口,释放该窗口分配的所有内存
cvDestroyWindow("Origin Image");
}
// OpenCVvideo.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
int main(int argc, char* argv[]) {
const char* inputVideo = "my.mp4";
//cvCaptureFromAVI(inputVideo);
//openCV 有如下定义:#define cvCaptureFromAVI cvCaptureFromFile
// #define cvCaptureFromFile cvCreateFileCapture
//cvCreateFileCapture(inputVideo) cvCaptureFromAVI(inputVideo);
CvCapture* capture = cvCreateFileCapture(inputVideo);
int i = 0;
IplImage* img = 0;
char image_name[25];
cvNamedWindow("video");
//计算每秒帧数
double fps = cvGetCaptureProperty(capture,CV_CAP_PROP_FPS);
printf("fps=%d\n", (int)fps);
//读取和显示
while (1)
{
//获取一帧图片
//cvQueryFrame()函数实际上是cvGrabFrame()和 cvRetrieveFrame()的一个组合
img = cvQueryFrame(capture);
if (img == NULL)
break;
//显示
cvShowImage("video", img);
char key = cvWaitKey(20);
//将每一帧保存到images文件夹下
sprintf(image_name, "%s%d%s", "images\\image", ++i, ".jpg");//保存的图片名
cvSaveImage(image_name, img);
}
cvReleaseCapture(&capture);
cvDestroyWindow("video");
return 0;
}
这是保存的帧,在images文件夹下
代码如下:
void testROI(){
IplImage *image = cvLoadImage("lenaRGB.tif");
cout << "Width:" << image->width<height<widthStep<
函数原型:
void imageSplit(){
IplImage *image = cvLoadImage("RGB.tif");
IplImage *imgR = NULL, *imgG = NULL, *imgB = NULL , *imgMerge=NULL;
//根据图像深度大小和图像深度,创建单通道图像
imgR = cvCreateImage(cvGetSize(image), image->depth, 1);
imgG = cvCreateImage(cvGetSize(image), image->depth, 1);
imgB = cvCreateImage(cvGetSize(image), image->depth, 1);
//创建一个预合成的三通道图像
imgMerge = cvCreateImage(cvGetSize(image), image->depth, 3);
//分离出来的顺序是逆序的 cvSplit(pImg,bImg,gImg,rImg,0)
cvSplit(image, imgB, imgG, imgR, NULL);
cvNamedWindow("Origin", CV_WINDOW_AUTOSIZE);
cvNamedWindow("Red", CV_WINDOW_AUTOSIZE);
cvNamedWindow("Green", CV_WINDOW_AUTOSIZE);
cvNamedWindow("Blue", CV_WINDOW_AUTOSIZE);
cvShowImage("Origin", image);
cvShowImage("Red", imgR);
cvShowImage("Green", imgG);
cvShowImage("Blue", imgB);
//合并顺序也是相反的
cvMerge(imgB, imgG, imgR, NULL, imgMerge);
cvNamedWindow("Merge", CV_WINDOW_AUTOSIZE);
cvShowImage("Merge", imgMerge);
cvWaitKey();
cvReleaseImage(&imgR);
cvReleaseImage(&imgG);
cvReleaseImage(&imgB);
cvReleaseImage(&image);
cvReleaseImage(&image);
cvReleaseImage(&imgMerge);
cvDestroyWindow("Origin");
cvDestroyWindow("Red");
cvDestroyWindow("Green");
cvDestroyWindow("Blue");
cvDestroyWindow("Merge");
}
结果如下:
void imageScale(){
IplImage *srcImage = cvLoadImage("lena.tif");
IplImage *dstImage = NULL;
double fScale = 0.5;
int deep = srcImage->depth;
int channel = srcImage->nChannels;
cout << "Deep:" << deep << endl << "Channel:" << channel << endl;
cout << "Width:" << srcImage->width << " Height:" << srcImage->height << endl;
CvSize size;
size.width = srcImage->width * fScale;
size.height = srcImage->height * fScale;
dstImage = cvCreateImage(size, deep, channel);
// CV_INTER_NN -最邻近插值 CV_INTER_LINEAR -双线性插值 CV_INTER_AREA --使用象素关系重采样
// CV_INTER_CUBIC -立方插值
cvResize(srcImage, dstImage, CV_INTER_CUBIC);
cvNamedWindow("Source", CV_WINDOW_AUTOSIZE);
cvShowImage("Source", srcImage);
cvNamedWindow("Scale", CV_WINDOW_AUTOSIZE);
cvShowImage("Scale", dstImage);
cvWaitKey();
cvSaveImage("scaleImageCUBIC.tif", dstImage);
cvReleaseImage(&srcImage);
cvReleaseImage(&dstImage);
cvDestroyWindow("Source");
cvDestroyWindow("Scale");
}
//利用高斯滤波器平滑图像
void smoothImage(){
//IplImage 结构体
IplImage *img = cvLoadImage("lenaNoise.tif");
cvNamedWindow("OriginImage", 0);
cvShowImage("OriginImage", img);
//3*3的高斯滤波器
IplImage *out_imageG = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3);
cvNamedWindow("GauImage", 0);
//3*3的中值滤波器
IplImage *out_imageM = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3);
cvNamedWindow("MedImage", 0);
cvSmooth(img, out_imageG, CV_GAUSSIAN, 3, 3);
cvShowImage("GauImage",out_imageG);
cvSmooth(img, out_imageM, CV_MEDIAN, 3, 3);
cvShowImage("MedImage", out_imageM);
cvWaitKey(0);
cvReleaseImage(&img);
cvReleaseImage(&out_imageG);
cvReleaseImage(&out_imageM);
cvDestroyWindow("OriginImage");
cvDestroyWindow("GauImage");
cvDestroyWindow("MedImage");
}
结果如下:如预期一样,中值滤波对于椒盐噪声的处理效果比较好