Opencv学习笔记一.docx
《Opencv学习笔记一.docx》由会员分享,可在线阅读,更多相关《Opencv学习笔记一.docx(24页珍藏版)》请在冰豆网上搜索。
![Opencv学习笔记一.docx](https://file1.bdocx.com/fileroot1/2022-11/29/6001ab62-c19a-440c-861c-79b1b9b24a6c/6001ab62-c19a-440c-861c-79b1b9b24a6c1.gif)
Opencv学习笔记一
Opencv学习笔记
(一)
一VS2015-openCV3.1.0-win10配置说明
注意本文是针对vs2015的,因为vs2015为vc14在以前的opencv中没有vc14,因此带来了很多的不便,本文对VS2015-openCV3.1.0配置进行说明。
1安装vs,opencv
vs2015安装与opencv3.1.0安装过程不予讲述。
2OpenCV3.1.0环境变量配置
右键属性->高级系统设置->环境变量->系统变量->找到Path->在变量值中添加相应路径,我的路径是
H:
\Opencv3.1.0\opencv\build\x64\vc14\bin
3VS中配置
<一>:
首先建立一个Win32控制台项目,然后选择空项目
<二>:
先在源文件下建立一个.cpp源文件命名为main.cpp
<三>:
然后点击视图,在视图下找到其他窗口,在其他窗口下找到属性管理器,点击打开,.然后便会有一个属性管理器的窗口了,接下来点开工程文件test,下边会有一个Debug|x64的文件夹,点开,下有名为Microsoft.Cpp.x64.user的文件,右键属性
<四>然后选择通用属性下的VC++目录,右边会有包含目录和库目录,点击包含目录,添加以下三条路径,其实这些都是刚才OpenCV相关解压文件所在的目录
H:
\Opencv3.1.0\opencv\build\include
H:
\Opencv3.1.0\opencv\build\include\opencv
H:
\Opencv3.1.0\opencv\build\include\opencv2
这三条路径要依据自己解压OpenCV3.1的路径进行修改
<五>:
再点击库目录添加下面一条路径
C:
\Opencv3.1.0\opencv\build\x64\vc14\lib
还是刚才的属性页面点击链接器,选择输入,会在右侧看到附加依赖项,添加下面文件opencv_world310d.lib
4测试
#include
#include
usingnamespacecv;
usingnamespacestd;
intmain()
{
cout<<"helloopencv"<IplImage*plmg=cvLoadImage("lena.jpg",1);//声明IplImage指针
cvNamedWindow("Image",1);//创建窗口
cvShowImage("Image",plmg);//显示图像
cvWaitKey(0);//等待按键如果没有这句,显示图片的那句就会一闪而过立刻销毁了
cvDestroyWindow("Image");
cvReleaseImage(&plmg);
return0;
}
注意:
1.这里用的是debugx64版本,要将vs中x86改成x64
2.图片放在项目的Debug下。
这里给出最新的opencv读图的方法
//!
[includes]
#include
#include
#include
#include
#include
//!
[includes]
//!
[namespace]
usingnamespacecv;
//!
[namespace]
usingnamespacestd;
intmain(intargc,char**argv)
{
//!
[load]
StringimageName("cute.jpg");//bydefault
if(argc>1)
{
imageName=argv[1];
}
//!
[load]
//!
[mat]
Matimage;
//!
[mat]
//!
[imread]
image=imread(imageName,IMREAD_COLOR);//Readthefile
//!
[imread]
if(image.empty())//Checkforinvalidinput
{
cout<<"Couldnotopenorfindtheimage"<:
endl;
return-1;
}
//!
[window]
namedWindow("Displaywindow",WINDOW_AUTOSIZE);//Createawindowfordisplay.
//!
[window]
//!
[imshow]
imshow("Displaywindow",image);//Showourimageinsideit.
//!
[imshow]
//!
[wait]
waitKey(0);//Waitforakeystrokeinthewindow
//!
[wait]
return0;
}
二Mat,图像的新容器
基础知识
自从版本2.0,OpenCV采用了新的数据结构,用Mat类结构取代了之前用extendedC写的cvMat和lplImage,更加好用啦,最大的好处就是更加方便的进行内存管理,对写更大的程序是很好的消息。
#include
#include
usingnamespacecv;
usingnamespacestd;
intmain(intargc,char*argv[])
{
Matimage;//声明类
image=imread("lena.jpg",IMREAD_COLOR);
if(!
image.data){//Checkforinvalidinput
cout<<"Couldnotopenorfindtheimage"<:
endl;
return-1;
}
Matgray_image;
cvtColor(image,gray_image,CV_BGR2GRAY);//将彩色图像变为灰度图像
imwrite("Gray_Image.jpg",gray_image);//writepicture
namedWindow("Colorimage",CV_WINDOW_AUTOSIZE);
namedWindow("Grayimage",CV_WINDOW_AUTOSIZE);
imshow("Colorimage",image);//原图
imshow("Grayimage",gray_image);//灰色
waitKey(0);
return0;
}
Mat解析
1.Mat是一个类,有构造函数,赋值函数等
1MatA,C;//createsjusttheheaderparts
2A=imread(argv[1],CV_LOAD_IMAGE_COLOR);//herewe’llknowthemethodused(allocatematrix)
3MatB(A);//Usethecopyconstructor
4C=A;//Assignmentoperator
2.如果要拷贝自己的矩阵:
1MatF=A.clone();
2MatG;
3A.copyTo(G);
3.构造函数解析
MatM(2,2,CV_8UC3,Scalar(0,0,255));
cout<<"M="<构造2*2的矩阵。
CV_[Thenumberofbitsperitem][SignedorUnsigned][TypePrefix]C[Thechannelnumber]
CV_8UC3meansweuseunsignedchartypesthatare8bitlongandeachpixelhasthreeofthesetoformthethreechannels.
4.与原始的转换
IplImage*img=cvLoadImage("greatwave.png",1);
Matmtx(img);//convertIplImage*->Mat
MatI;
IplImage*pI=&I.operatorIplImage();
CvMat*mI=&I.operatorCvMat();
5.改变矩阵creat()函数
不能用来初始化一个矩阵,它不是构造函数,它用来改变一个已有的矩阵的格式。
Create()function:
M.create(4,4,CV_8UC
(2));
cout<<"M="<6.Matlab类型初始化操作
MatE=Mat:
:
eye(4,4,CV_64F);
cout<<"E="<MatO=Mat:
:
ones(2,2,CV_32F);
cout<<"O="<MatZ=Mat:
:
zeros(3,3,CV_8UC1);
cout<<"Z="<三图像处理的基本操作
Opencv图像处理基本操作
1基本数据类型
图像有若干个通道,灰度图像只有一个通道,而彩色具有红,绿,蓝组成,但是OpenCv以逆序的方式来存储三个分量,还可以使用第四个透明度(alpha),可以使用img.channels()获取图像通道个数。
使用若干个位存储一副图像的每个像素,这被称为图像的深度,灰度图像为8位,即0-255个灰度级,可以用img.depth()获得图像的深度,其返回值为:
CV_8U-8-bitunsignedintegers(0..255)
CV_8S-8-bitsignedintegers(-128..127)
CV_16U-16-bitunsignedintegers(0..65535)
CV_16S-16-bitsignedintegers(-32768..32767)
CV_32S-32-bitsignedintegers(-2147483648..2147483647)
CV_32F-32-bitfloating-pointnumbers(-FLT_MAX..FLT_MAX,INF,NAN)
CV_64F-64-bitfloating-pointnumbers(-DBL_MAX..DBL_MAX,INF,NAN)
对于灰度图像和彩色图像,最常见的是CV_8U.
Matimg=imread("lena.png",IMREAD_GRAYSCALE);
Matfp;
img.convertTo(fp,CV_32F);//改变图像的深度
1
2
3
2像素级访问
1.第一种方法:
模板函数at<>
ucharpixel=img.at(0,0);//获得灰度图像0,0点像素
Vec3bpixel=img.at(0,0);//获得3波段图像的第一个波段(0,0)像素。
1
2
第一种方法,效率不高,必须定位到他所在的位置
2.第二种方法:
函数ptr
他返回图像特定行的指针。
因此可以得到每一行的数据,时间复杂度降低,
如下代码获取一副彩色图像的每个像素值。
//时间复杂度大大降低!
!
!
ucharR,G,B;
for(inti=0;iVec3bpixRow=img.ptr(i);
for(intj=0;jB=pixRow[j][0];
G=pixRow[j][1];
R=pixRow[j][2];
}
测量程序用时可用函数:
doubleto=(double)getTickCount();
elapsed=((double)getTickCount()-to)/getTickFrenquency()
图像位运算
可以用掩码对一个图像进行处理,位元算有:
voidbitwise_and(InputArraysrc1,InputArraysrc2,OutputArraydst,InputArraymask=noArray())
其中src1是原始的图像,src2是掩码,dst为输出
一个例子:
#include
#include
usingnamespacecv;
usingnamespacestd;
intmain(){
Matimg=imread("cute.jpg",1);
if(img.empty())
cout<<"cannotloadimage"<imshow("Origin",img);
Matmask(img.rows,img.cols,CV_8UC3,Scalar(0,0,0));
circle(mask,Point(img.rows/2,img.cols/2-35),220,Scalar(255,255,255),-1);//画一个圆
imshow("Mask",mask);
//执行位操作
Matr;
bitwise_and(img,mask,r);
imshow("Bit_and",r);
waitKey(0);
return0;
}
如下所示的图像处理过程:
分别为原始图像,掩模,计算后的图像
1.Adding(blending)twoimagesusingOpenCV
将两张图像以线性组合的方式合并成一张图像,注意的是,两张图像的大小应该相同。
g(x)=(1-a
)*f0(x)+
a*f1(x)g(x)为生成的矩阵,f0(x),f1(x)为要合并的两个矩阵。
a为尺度。
用到的函数原型:
C++:
voidaddWeighted(InputArraysrc1,doublealpha,InputArraysrc2,doublebeta,doublegamma,OutputArraydst,intdtype=-1)
#include
#include
#include
#include
#include
usingnamespacecv;
usingnamespacestd;
intmain(intargc,char**argv)
{
doublealpha=0.5;doublebeta;doubleinput;
Matsrc1,src2,dst;
///Asktheuserenteralpha
std:
:
cout<<"SimpleLinearBlender"<:
endl;
std:
:
cout<<"-----------------------"<:
endl;
std:
:
cout<<"*Enteralpha[0-1]:
";
std:
:
cin>>input;
///Weusethealphaprovidedbytheuserifitisbetween0and1
if(input>=0.0&&input<=1.0)
alpha=input;
///Readimage(samesize,sametype)
src1=imread("LinuxLogo.jpg");
src2=imread("WindowsLogo.jpg");
if(!
src1.data){printf("Errorloadingsrc1\n");return-1;}
if(!
src2.data){printf("Errorloadingsrc2\n");return-1;}
///CreateWindows
namedWindow("LinearBlend",1);
beta=(1.0-alpha);
addWeighted(src1,alpha,src2,beta,0.0,dst);
imshow("LinearBlend",dst);
waitKey(0);
return0;
}
当a=0时,此时只有window的logo
2.Changingthecontrastandbrightnessofanimage
改变图像的对比度和亮度
基础的公式为:
g(i;j)=
a*f(i,j)+
b
whereiandjindicatesthatthepixelislocatedinthei-throwandj-thcolumn.
获得一个图片的像素我们用image.at(y,x)[c]这里的y为行,x为列,c代表R,GorB(0,1or2)
intmain(intargc,char**argv)
{
doublealpha;/**intbeta;/**///Readimagegivenbyuser
Matimage=imread("cute.jpg");
Matnew_image=Mat:
:
zeros(image.size(),image.type());//copytheoriginpicturesize,andtype
///Initializevalues
std:
:
cout<<"BasicLinearTransforms"<:
endl;
std:
:
cout<<"-------------------------"<:
endl;
std:
:
cout<<"*Enterthealphavalue[1.0-3.0]:
";std:
:
cin>>alpha;
std:
:
cout<<"*Enterthebetavalue[0-100]:
";std:
:
cin>>beta;
///Dotheoperationnew_image(i,j)=alpha*image(i,j)+beta
for(inty=0;yfor(intx=0;xfor(intc=0;c<3;c++){
new_image.at(y,x)[c]=
saturate_cast(alpha*(image.at(y,x)[c])+beta);//saturate_casttomakesurethevaluesarevalid.
}
}
}
namedWindow("OriginalImage",1);
namedWindow("NewImage",1);
imshow("OriginalImage",image);
imshow("NewImage",new_image);
waitKey();
return0;
}
示例如下:
可以看到改变的图片的对比度和亮度。
这里可以用函数image.convertTo(new_image,-1,alpha,beta);来代替for循环,它会更有效率。
BasicDrawing
1.定义一个点2D
Pointpt;
pt.x=10;
pt.y=8;
Pointpt=Point(10,8);
2.画椭圆ellipse原型
voidellipse(InputOutputArrayimg,Pointcenter,Sizeaxes,
doubleangle,doublestartAngle,doubleendAngle,
constScalar&color,intthickness=1,
intlineType=LINE_8,intshift=0);
后面三个为默认的参数,可以不写。
//自己写的函数,指定img,和角度
voidMyEllipse(Matimg,doubleangle)
{
intthickness=2;
intlineType=8;
ellipse(img,
Point(w/2,w/2),
Size(w/4,w/16),
angle,
0,
360,
Scalar(255,0,0),//为颜色
thickness,
lineType);
}
//**调用方法:
**
MyLine(rook_image,Point(0,15*w/16),Point(w,15*w/16));
3.画线段
函数原型
voidline(InputOutputArrayimg,Pointpt1,Pointpt2,constScalar&color,
intthickness=1,intlineType=LINE_8,intshift=0);
RandomgeneratorandtextwithOpenCV
随机数产生类Ran