OpenCV入门学习第一篇
阅读原文时间:2021年04月20日阅读:1

      接触到图像处理,不免要用到OpenCV,丰富的图像处理函数,不仅在追求高性能(基于C实现)上而且开源库更是方便开发者不断扩展openCV库。是计算机视觉研究方向的必要开发工具。由于刚刚接触OpenCV,本文主要是是对于OpenCV一些简单实例的测试与实现。

  1、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:配置环境变量后注意重启电脑,重启,之前以为不用重启,但是无法是配置生效,所以还是乖乖重启吧。

   2、第一个OpenCV例子----显示一张图片

//第一个例子:显示图像
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");
}

结果图:帅气的米勒

3、利用OpenCV播放视频

// 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;
}

输出:fps=29   

这是保存的帧,在images文件夹下

4、OpenCV设定ROI区域,ROI=region of interesting,就是设定感兴趣的区域,如果对图像设定了ROI区域,则接下来相应的图像操作只会作用于该区域,直到释放该区域。

代码是将一部分区域设置为白色,如果不设置ROI区域,则整幅图像都变成白色。所以,在图像处理中这是经常用到的方法,我们只关注于我们感兴趣的图像区域。

代码如下:

void testROI(){
    IplImage *image = cvLoadImage("lenaRGB.tif");
    cout << "Width:" << image->width<<endl;
    cout << "Height:" << image->height<<endl;
    cout << "Step:" << image->widthStep<<endl;
    //设置ROI
    cvSetImageROI(image, cvRect(0, 100, 100, 100));
    //ROI 区域加上一个标量
    cvAddS(image, cvScalar(255,255,255), image);
    //释放ROI,否则只会显示ROI 区域
    cvResetImageROI(image);

    //show image
    cvNamedWindow("ROI", 1);
    cvShowImage("ROI", image);
    cvWaitKey();

    cvReleaseImage(&image);
    cvDestroyWindow("ROI");
}

4、彩色图像三通道图像提取

函数原型:

  1. void cvSplit(const CvArr* src,CvArr *dst0,CvArr *dst1, CvArr *dst2, CvArr *dst3);

注意:该函数分离是按BGR顺序分离的。

代码如下:

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");

}

结果如下:

5、图像缩放

图像缩放-即插值函数的调用,OpenCV提供了几种插值方法。

代码:

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");
}

6、图像平滑

函数原型: void cvSmooth( const CvArr* src, CvArr* dst,int smoothtype=CV_GAUSSIAN,int param1, int param2, double param3, double param4 );

**smoothtype平滑方法:
**CV_BLUR_NO_SCALE(简单不带尺度变换的模糊) - -对每个象素的 param1×param2 领域求和。如果邻域大小是变化的,可以事先利用函数 cvIntegral 计算积分图像。
CV_BLUR (simple blur)- -对每个象素param1×param2邻域求和并做尺度变换 1/(param1×param2)。
CV_GAUSSIAN(gaussian blur) - -对图像进行核大小为 param1×param2 的高斯卷积。
CV_MEDIAN(median blur) - -对图像进行核大小为param1×param1 的中值滤波 (邻域是方的)。
CV_BILATERAL(双向滤波) - -应用双向 3x3 滤波,彩色 sigma=param1,空间 sigma=param2.。

以下实例是对带有椒盐噪声的图像进行处理:高斯滤波和中值滤波

//利用高斯滤波器平滑图像
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");
}

结果如下:如预期一样,中值滤波对于椒盐噪声的处理效果比较好

7、.

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器