首页 > 代码库 > [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 )
[opencv]学习之路