[opencv]学习之路

参考这个人的教程:

本系列文章由@浅墨_毛星云 出品,转载请注明出处。

文章链接: http://blog.csdn.net/poem_qianmo/article/details/21176257

作者:毛星云(浅墨) 邮箱: [email protected]

写作当前博文时配套使用的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 = 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= ( 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 = 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 = 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 )  

时间: 2024-11-05 17:21:07

[opencv]学习之路的相关文章

Opencv学习之路—Opencv下基于HOG特征的KNN算法分类训练

在计算机视觉研究当中,HOG算法和LBP算法算是基础算法,但是却十分重要.后期很多图像特征提取的算法都是基于HOG和LBP,所以了解和掌握HOG,是学习计算机视觉的前提和基础. HOG算法的原理很多资料都可以查到,简单来说,就是将图像分成一个cell,通过对每个cell的像素进行梯度处理,进而根据梯度方向和梯度幅度来得到cell的图像特征.随后,将每个cell的图像特征连接起来,得到一个BLock的特征,进而得到一张图片的特征.Opencv当中自带HOG算法,可以直接调用,进行图像的特征提取.但

opencv学习之路(21)、模板匹配及应用

一.模板匹配概念 二.单模板匹配 1 #include "opencv2/opencv.hpp" 2 #include <iostream> 3 using namespace std; 4 using namespace cv; 5 6 void main() 7 { 8 Mat temp=imread("E://mu.jpg"); 9 Mat src=imread("E://lena.jpg"); 10 Mat dst=src.c

opencv学习之路(25)、轮廓查找与绘制(四)——正外接矩形

一.简介 二.外接矩形的查找绘制 1 #include "opencv2/opencv.hpp" 2 using namespace cv; 3 void main() 4 { 5 //外接矩形的查找绘制 6 Mat srcImg =imread("E://12.jpg"); 7 imshow("src",srcImg); 8 Mat dstImg = srcImg.clone(); //原图备份 9 cvtColor(srcImg, srcIm

opencv学习之路(20)、直方图应用

一.直方图均衡化--equalizeHist() 1 #include "opencv2/opencv.hpp" 2 using namespace cv; 3 4 void main() 5 { 6 Mat srcImg = imread("E://02.jpg", 0); //以灰度方式打开,需要输入单通道图像 7 imshow("src", srcImg); 8 Mat dstImg; //均衡化后的图像 9 equalizeHist(sr

opencv学习之路(17)、边缘检测

一.概述 二.canny边缘检测 1 #include "opencv2/opencv.hpp" 2 using namespace cv; 3 4 void main() 5 { 6 //Canny边缘检测 7 Mat srcImg = imread("E://1.png",0); //0表示以灰度图读入,彩色图和灰度图进行边缘检测时略有不同,建议使用灰度图 8 //medianBlur(srcImg, srcImg,5);//中值滤波 9 imshow(&quo

opencv学习之路(5)、鼠标和滑动条操作

一.鼠标事件 1 #include<opencv2/opencv.hpp> 2 #include<iostream> 3 using namespace cv; 4 using namespace std; 5 6 Mat img(500,500,CV_8UC3,Scalar(255,255,255));//定义成全局变量 7 8 void OnMouse(int event,int x,int y,int flags,void* param){ 9 if(event==CV_EV

opencv学习之路(4)、Mat类介绍,基本绘图函数

一.Mat类创建 1 #include <opencv2/opencv.hpp> 2 using namespace cv; 3 4 void main(){ 5 Mat img1=imread("E://1.jpg"); 6 Mat img2(img1); 7 Mat img3=img1; 8 Mat img4=img1.clone(); 9 Mat img5; 10 img1.copyTo(img5); 11 12 cvtColor(img1,img1,CV_BGR2H

opencv学习之路(26)、轮廓查找与绘制(五)——最小外接矩形

一.简介 二.轮廓最小外接矩形的绘制 1 #include "opencv2/opencv.hpp" 2 using namespace cv; 3 4 void main() 5 { 6 //轮廓最小外接矩形的绘制 7 Mat srcImg = imread("E://00.png"); 8 Mat dstImg = srcImg.clone(); 9 cvtColor(srcImg, srcImg, CV_BGR2GRAY); 10 threshold(srcI

opencv学习之路(13)、图像阈值化

一.图像阈值化简介 二.固定阈值 三.自适应阈值 1 #include<opencv2/opencv.hpp> 2 using namespace cv; 3 4 void main(){ 5 Mat src=imread("E://1.jpg",0);//以灰度模式读入 6 Mat dst; 7 //threshold(src,dst,100,255,CV_THRESH_BINARY); 8 //adaptiveThreshold(src,dst,255,CV_ADAPT

opencv学习之路(6)、鼠标截图,滑动条播放视频

一.鼠标截图 1 #include<opencv2/opencv.hpp> 2 #include<iostream> 3 using namespace cv; 4 using namespace std; 5 6 Mat img=imread("E://1.jpg"); 7 Mat temp=img.clone(); 8 Mat ROI; 9 Point pt; 10 bool flag=false; 11 12 void onMouse(int event,