首页 > 代码库 > [opencv]学习之路

[opencv]学习之路

参考这个人的教程:
本系列文章由@浅墨_毛星云 出品,转载请注明出处。
文章链接: http://blog.csdn.net/poem_qianmo/article/details/21176257
作者:毛星云(浅墨) 邮箱: happylifemxy@163.com
写作当前博文时配套使用的OpenCV版本: 2.4.8


2016年9月7日
花了一个早上,才配置好了环境。然后系统有错误就开始崩盘,我也是跟着浅墨大神走的,最后还是女神比较给力,遇见了跟我一样的情况,在她的指导下,走出困境!
基本结构:
技术分享
cv::Mat类是用于载入图像以及其他矩阵数据的数据结构。
技术分享
namedWindow函数,用于创建一个窗口。
函数举例说明:

#include<iostream>  
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
using namespace cv;  
int main()  
{  
    // 读入一张叫做pic的图片(游戏原画)  
    Mat img1=imread("pic.jpg",CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);//载入最真实的图像  
    Mat img2=imread("pic.jpg",0);//载入灰度图  
    Mat img3=imread("pic.jpg",199);//载入3通道的彩色图像  
    // 创建一个名为 "原画"窗口  
    namedWindow("原画");  
    // 在窗口中原画  
    imshow("原画",img1);  
    // 等待6000 ms后窗口自动关闭  
    // 创建一个名为 "灰度画"窗口  
    namedWindow("灰度图");  
    // 在窗口中灰度画  
    imshow("灰度画",img2);  
    // 创建一个名为 "彩色画"窗口  
    namedWindow("彩色图");  
    // 在窗口中彩色画  
    imshow("彩色图",img3);  
    // 等待6000 ms后窗口自动关闭  
    waitKey(600000);  
}  

技术分享

输出图像到文件:imwrite函数用于将图像保存到指定的文件
imshow 函数:在指定的窗口中显示一幅图像。

任务1:为一个图片加上一个logo
按照浅墨的方法,为什么我就加不上这个logo呢,难不成是图片大小或者是某个参数的问题?
我换了一张图片以后程序可以通过。
现在看看,图片每个参数时什么意思。
具体代码:

#include<iostream>  
#include <stdlib.h>
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
using namespace std;
using namespace cv;  
int main()  
{  
    Mat image=imread("pic.jpg");//读取原图像1
    Mat logo=imread("logo.jpg");//读取logo图像
    namedWindow("未加logo图像");
    imshow("未加logo图像",image);
    namedWindow("logo图像");
    imshow("logo图像",logo);
    Mat imageROI;
    imageROI=image(Range(10,10+logo.rows),Range(10,10+logo.cols));//这里的位置就是坐标,同时需要注意的是:image只是一个变量的名称
    addWeighted(imageROI,0.5,logo,0.3,0.,imageROI);
    namedWindow("【4】原画+logo图");  
    imshow("【4】原画+logo图",image);  
    imwrite("加入logo后的图像.jpg",image);  //在同一文件目录下输出
    waitKey(600000);  
    return 0;
}  

技术分享
设定感兴趣区域ROI
定义方法有两种:

//定义一个Mat类型并给其设定ROI区域  
Mat imageROI;  
//方法一  
imageROI=image(Rect(500,250,logo.cols,logo.rows)); //imageROI=image(a,b,c,d);a,表示图片左上角起点位置的横坐标,b表示起点位置纵坐标,c,d表示插入的图片的大小,实例中用logo.cols和logo.rows表示是引用这这一个参数

另一种定义ROI的方式是指定感兴趣行或列的范围(Range)

imageROI=Image(Range(500,500+logoImage.rows),Range(250,250+logoImage.cols));  

但是具体这两种方法怎么换算,我就不知道了,我认为还是第一种方法会比较好。
浅墨用mask函数进行掩模的时候,只是对黑色的部分进行了掩模,但是我是白色的图片效果很差。

addWeighted(imageROI,0.9,logo,0.3,0.,imageROI);//addWeighted(a,b,c,d,e,f,g)总共7个参数,其中a是:表示需要添加的对象//b表示第一个数组的权重//c(不重要)表示表示第二个数组,它需要和第一个数组拥有相同的尺寸和通道数//d表示第二个数组的权重//f表示输出数组//其他都不重要

改变权重以后
技术分享
tip:system("color 5E");//这条语句可是改变运行框的颜色
例如:
技术分享
然后是将颜色分离函数:
第五篇:
spilt函数:将一个多通道数组分离成几个单通道数组
merge()函数的功能:是将多个数组组合合并成一个多通道的数组。

下载粘贴一下真正在使用中的代码怎么写:

//-----------------------------------【程序说明】----------------------------------------------  
//  程序名称::【OpenCV入门教程之四】 ROI区域图像叠加&初级图像混合 全剖析   配套源码  
// VS2010版   OpenCV版本:2.4.8  
//     2014年3月10日 Create by 浅墨  
//    图片素材出处:dota2原画 dota2logo   
//     浅墨的微博:@浅墨_毛星云  
//------------------------------------------------------------------------------------------------  

//-----------------------------------【头文件包含部分】---------------------------------------  
//     描述:包含程序所依赖的头文件  
//----------------------------------------------------------------------------------------------                                                                                      
#include <cv.h>  
#include <highgui.h>  
#include <iostream>  

//-----------------------------------【命名空间声明部分】---------------------------------------  
//     描述:包含程序所使用的命名空间  
//-----------------------------------------------------------------------------------------------    
using namespace cv;  
using namespace std;  


//-----------------------------------【全局函数声明部分】--------------------------------------  
//     描述:全局函数声明  
//-----------------------------------------------------------------------------------------------  
bool ROI_AddImage();  
bool LinearBlending();  
bool ROI_LinearBlending();  

//-----------------------------------【main( )函数】--------------------------------------------  
//     描述:控制台应用程序的入口函数,我们的程序从这里开始  
//-----------------------------------------------------------------------------------------------  
int main(  )  
{  
       system("color 5E");  

       if(ROI_AddImage()&& LinearBlending( )&&ROI_LinearBlending( ))  
       {  
              cout<<endl<<"嗯。好了,得出了你需要的图像~! : )";  
       }  

       waitKey(0);  
       return 0;  
}  

//----------------------------------【ROI_AddImage( )函数】----------------------------------  
// 函数名:ROI_AddImage()  
//     描述:利用感兴趣区域ROI实现图像叠加  
//----------------------------------------------------------------------------------------------  
bool ROI_AddImage()  
{  

       //【1】读入图像  
       Mat srcImage1= imread("dota_pa.jpg");  
       Mat logoImage= imread("dota_logo.jpg");  
       if(!srcImage1.data ) { printf("你妹,读取srcImage1错误~! \n"); return false; }  
       if(!logoImage.data ) { printf("你妹,读取logoImage错误~! \n"); return false; }  

       //【2】定义一个Mat类型并给其设定ROI区域  
       Mat imageROI= srcImage1(Rect(200,250,logoImage.cols,logoImage.rows));  

       //【3】加载掩模(必须是灰度图)  
       Mat mask= imread("dota_logo.jpg",0);  

       //【4】将掩膜拷贝到ROI  
       logoImage.copyTo(imageROI,mask);  

       //【5】显示结果  
       namedWindow("<1>利用ROI实现图像叠加示例窗口");  
       imshow("<1>利用ROI实现图像叠加示例窗口",srcImage1);  

       return true;  
}  


//---------------------------------【LinearBlending()函数】-------------------------------------  
// 函数名:LinearBlending()  
// 描述:利用cv::addWeighted()函数实现图像线性混合  
//--------------------------------------------------------------------------------------------  
bool LinearBlending()  
{  
       //【0】定义一些局部变量  
       double alphaValue = http://www.mamicode.com/0.5;  
       double betaValue;  
       Mat srcImage2, srcImage3, dstImage;  

       //【1】读取图像 ( 两幅图片需为同样的类型和尺寸 )  
       srcImage2= imread("mogu.jpg");  
       srcImage3= imread("rain.jpg");  

       if(!srcImage2.data ) { printf("你妹,读取srcImage2错误~! \n"); return false; }  
       if(!srcImage3.data ) { printf("你妹,读取srcImage3错误~! \n"); return false; }  

       //【2】进行图像混合加权操作  
       betaValue= http://www.mamicode.com/( 1.0 - alphaValue );  
       addWeighted(srcImage2, alphaValue, srcImage3, betaValue, 0.0, dstImage);  

       //【3】创建并显示原图窗口  
       namedWindow("<2>线性混合示例窗口【原图】 by浅墨", 1);  
       imshow("<2>线性混合示例窗口【原图】 by浅墨", srcImage2 );  

       namedWindow("<3>线性混合示例窗口【效果图】 by浅墨", 1);  
       imshow("<3>线性混合示例窗口【效果图】 by浅墨", dstImage );  

       return true;  

}  

//---------------------------------【ROI_LinearBlending()】-------------------------------------  
// 函数名:ROI_LinearBlending()  
// 描述:线性混合实现函数,指定区域线性图像混合.利用cv::addWeighted()函数结合定义  
//                     感兴趣区域ROI,实现自定义区域的线性混合  
//--------------------------------------------------------------------------------------------  
bool ROI_LinearBlending()  
{  

       //【1】读取图像  
       Mat srcImage4= imread("dota_pa.jpg",1);  
       Mat logoImage= imread("dota_logo.jpg");  

       if(!srcImage4.data ) { printf("你妹,读取srcImage4错误~! \n"); return false; }  
       if(!logoImage.data ) { printf("你妹,读取logoImage错误~! \n"); return false; }  

       //【2】定义一个Mat类型并给其设定ROI区域  
       Mat imageROI;  
              //方法一  
       imageROI=srcImage4(Rect(200,250,logoImage.cols,logoImage.rows));  
       //方法二  
       //imageROI=srcImage4(Range(250,250+logoImage.rows),Range(200,200+logoImage.cols));  

       //【3】将logo加到原图上  
       addWeighted(imageROI,0.5,logoImage,0.3,0.,imageROI);  

       //【4】显示结果  
       namedWindow("<4>区域线性图像混合示例窗口 by浅墨");  
       imshow("<4>区域线性图像混合示例窗口 by浅墨",srcImage4);  

       return true;  
}  

至少在这个代码中,让我知道了什么是面向对象,bool类型,封装的作用。

第六篇:
创建轨迹条:createTrackbar
我还是不会用,这个到底那个参数对应的那个变量呢?
回调函数这部分不懂,但是效果图是出来的。
技术分享
技术分享
绝对美!
第七篇:主要是讲的cmake的东西,用来查看源代码的。
第八篇:boxFilter、blur和GaussianBlur这三个函数
boxFilter函数是方框滤波,来模糊图片

//进行滤波操作  
       Mat out;  
       boxFilter(image, out, -1,Size(5, 5));  

       //显示效果图 
       //boxFilter(a, b, c,d);a是输入的图像,b是输出的图像,c=-1,-1代表使用原图深度,d是,Size类型的ksize,内核的大小。一般这样写Size( w,h )来表示内核的大小( 其中,w 为像素宽度, h为像素高度)。Size(3,3)就表示3x3的核大小,Size(5,5)就表示5x5的核大小,值越大,越模糊
       imshow("均值滤波【效果图】" ,out );  

技术分享

均值滤波:
调用函数的格式更加简单

Mat out;  
       blur(image, out, Size(7, 7));//
      blur(a,b,c)//a是输入图像,b是输出图像,c和上个函数一样,控制着虚化。 

技术分享

高斯滤波:

Mat out;  
GaussianBlur( image, out, Size( 5, 5 ), 0, 0 );//GaussianBlur( a,b, c, 0, 0 ); a,输入,b输出,c就是size,d是高斯核函数在X方向的的标准偏差,
f,示高斯核函数在Y方向的的标准偏差

第九篇:非线性滤波(包括中值滤波和双边滤波)

中值滤波:

medianBlur( image, out, 7);  //
第一个参数,输入,第二个参数,输出,第三个参数:必须是>1的奇数,越大越虚化

双边滤波

Mat out;  
bilateralFilter( image, out, 25, 25*2, 25/2 ); //第一个参数:输入;第二个参数输出;第三个参数:越大月虚化//第四个参数:颜色空间滤波器的sigma值。这个参数的值越大,就表明该像素邻域内有更宽广的颜色会被混合到一起,产生较大的半相等颜色区域//第五个参数:坐标空间的标注方差。他的数值越大,意味着越远的像素会相互影响,从而使更大的区域足够相似的颜色获取相同的颜色。当d>0,d指定了邻域大小且与sigmaSpace无关。否则,d正比于sigmaSpace。

双边滤波效果,让我想起了智能手机上的背景虚化,原来是这么来的。效果很好:
技术分享
第十篇:膨胀
可以看出衣服上膨胀啦

Mat image = imread("1.jpg");  
//获取自定义核  
        Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));  
        Mat out;  
        //进行膨胀操作  
        dilate(image, out, element); //第一参数输入,第二个参数输出 

技术分享
技术分享

腐蚀函数

//载入原图   
        Mat image = imread("1.jpg");  
//获取自定义核  
        Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));  
        Mat out;  
        //进行腐蚀操作  
        erode(image,out, element);  

与膨胀函数相似。
第十一章:
开运算,黑帽,顶帽等操作。

Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));   
       //进行形态学操作  
       morphologyEx(image,image, MORPH_OPEN, element);  //第一个参数输入,第二个参数输出,

第三个参数:
技术分享
第四个就写element同前面。
第十二章:
边缘检测

//载入原始图   
       Mat src = http://www.mamicode.com/imread("1.jpg");  //工程目录下应该有一张名为1.jpg的素材图  
       Canny(src, src, 3, 9,3 );  //第一参数:输入图像;第二个参数:输出图像,第三个参数:第一个滞后性阈值;第四个参数,第二个滞后性阈值(推荐的高低阈值比在2:1到3:1之间。);第五个参数:表示应用Sobel算子的孔径大小,其有默认值3。
       imshow("【效果图】Canny边缘检测", src);  

Sobel算子:

Sobel (  
InputArray src,//输入图  
 OutputArray dst,//输出图  
 int ddepth,//输出图像的深度  
 int dx,  
 int dy,  
 int ksize=3,  
 double scale=1,  
 double delta=0,  
 int borderType=BORDER_DEFAULT );  

技术分享

//-----------------------------------【头文件包含部分】---------------------------------------  
//            描述:包含程序所依赖的头文件  
//----------------------------------------------------------------------------------------------  
#include <opencv2/opencv.hpp>  
#include<opencv2/highgui/highgui.hpp>  
#include<opencv2/imgproc/imgproc.hpp>  

//-----------------------------------【命名空间声明部分】---------------------------------------  
//            描述:包含程序所使用的命名空间  
//-----------------------------------------------------------------------------------------------  
using namespace cv;  


//-----------------------------------【main( )函数】--------------------------------------------  
//            描述:控制台应用程序的入口函数,我们的程序从这里开始  
//-----------------------------------------------------------------------------------------------  
int main( )  
{  
    //【0】变量的定义  
    Mat src,src_gray,dst, abs_dst;  

    //【1】载入原始图    
    src = http://www.mamicode.com/imread("1.jpg");  //工程目录下应该有一张名为1.jpg的素材图  

    //【2】显示原始图   
    imshow("【原始图】图像Laplace变换", src);   

    //【3】使用高斯滤波消除噪声  
    GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT );  

    //【4】转换为灰度图  
    cvtColor( src, src_gray, CV_RGB2GRAY );  

    //【5】使用Laplace函数  
    Laplacian( src_gray, dst, CV_16S, 3, 1, 0, BORDER_DEFAULT );  

    //【6】计算绝对值,并将结果转换成8位  
    convertScaleAbs( dst, abs_dst );  

    //【7】显示效果图  
    imshow( "【效果图】图像Laplace变换", abs_dst );  

    waitKey(0);   

    return 0;   
}  
Laplacian(InputArray src,OutputArray dst, int ddepth, int ksize=1, double scale=1, double delta=0, intborderType=BORDER_DEFAULT );  

技术分享
scharr滤波器

Scharr(  
InputArray src, //源图  
 OutputArray dst, //目标图  
 int ddepth,//图像深度  
 int dx,// x方向上的差分阶数  
 int dy,//y方向上的差分阶数  
 double scale=1,//缩放因子  
 double delta=0,// delta值  
 intborderType=BORDER_DEFAULT )// 边界模式  

技术分享
resize( )为OpenCV中专职调整图像大小的函数。

 resize(InputArray src,OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR )  

技术分享
pyrUp( )函数的作用是放大一张图片。

pyrUp(InputArray src, OutputArraydst, const Size& dstsize=Size(), int borderType=BORDER_DEFAULT )  

技术分享

pyrDown( )函数的作用是缩小一张照片

 pyrDown(InputArray src,OutputArray dst, const Size& dstsize=Size(), int borderType=BORDER_DEFAULT)  

技术分享
第14章:
HoughLines()可以找出采用标准霍夫变换的二值图像线条

HoughLines(InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn=0, double stn=0 )  

第一个参数是输入图片;
技术分享
PS:可以通过调节line(dstImage, pt1, pt2, Scalar(55,100,195), 1, CV_AA);一句Scalar(55,100,195)参数中G、B、R颜色值的数值,得到图中想要的线条颜色。
HoughLinesP()在HoughLines的基础上末尾加了一个代表Probabilistic(概率)的P,表明它可以采用累计概率霍夫变换(PPHT)来找出二值图像中的直线。

HoughLinesP(InputArray image, OutputArray lines, double rho, double theta, int threshold, double minLineLength=0, double maxLineGap=0 )  

技术分享

<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

    [opencv]学习之路