[opencv]学习之路
Posted David_Han008
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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()函数的功能:是将多个数组组合合并成一个多通道的数组。
图像亮度和对比度:实现方式就是点操作
第六篇:
创建轨迹条:createTrackbar
createTrackbar(conststring& trackbarname, conststring& winname,
int* value, int count, TrackbarCallback onChange=0,void* userdata=0);
第一个参数是轨迹条的名字,第二个参数是窗口的名字,第三个参数是滑块的位置,第四个参数是滑块的最大值(最小值始终从零开始)第五个参数,指向回调指针的名字,第六个参数,表示没有回调函数的数据。
getTrackPos()函数:用于获取当前轨迹条的位置并且返回。
getTrackbarPos(a,b)//a表示轨迹条的名字,b表示轨迹条窗口的名字
在opencv中的鼠标操作:
利用SetMouseCallback函数来实现,(为指定函数设置鼠标回调函数)
setMouseCallback(a,b,c)//a表示窗口的名字,b可以通过下面的例子来说明,c是用户定义的传递到回调函数的参数。
rect这个对象是用来存储成对出现的参数
C++的RNG类。它可以压缩一个64位的i整数并可以得到scalar和array的随机数
代码总是敲不对,那我现吧这个这些功能实现,然后再说:
然后实现了鼠标的功能:
代码:
#include <opencv2/opencv.hpp>
using namespace cv;
//-----------------------------------【宏定义部分】--------------------------------------------
// 描述:定义一些辅助宏
//------------------------------------------------------------------------------------------------
#define WINDOW_NAME "【程序窗口】" //为窗口标题定义的宏
//------------------------------------------------------------------------------------------------
void on_MouseHandle(int event, int x, int y, int flags, void* param);
void DrawRectangle(cv::Mat& img, cv::Rect box);
//-----------------------------------------------------------------------------------------------
Rect g_rectangle;
bool g_bDrawingBox = false;//是否进行绘制
RNG g_rng(12345);
int main(int argc, char** argv)
{
//【1】准备参数
g_rectangle = Rect(-1, -1, 0, 0);
Mat srcImage(600, 800, CV_8UC3), tempImage;
srcImage.copyTo(tempImage);
g_rectangle = Rect(-1, -1, 0, 0);
srcImage = Scalar::all(0);
namedWindow(WINDOW_NAME);
setMouseCallback(WINDOW_NAME, on_MouseHandle, (void*)&srcImage);
while (1)
{
srcImage.copyTo(tempImage);//拷贝源图到临时变量
if (g_bDrawingBox) DrawRectangle(tempImage, g_rectangle);//当进行绘制的标识符为真,则进行绘制
imshow(WINDOW_NAME, tempImage);
if (waitKey(10) == 27) break;//按下ESC键,程序退出
}
return 0;
}
void on_MouseHandle(int event, int x, int y, int flags, void* param)
{
Mat& image = *(cv::Mat*) param;
switch (event)
{
//鼠标移动消息
case EVENT_MOUSEMOVE:
{
if (g_bDrawingBox)//如果是否进行绘制的标识符为真,则记录下长和宽到RECT型变量中
{
g_rectangle.width = x - g_rectangle.x;
g_rectangle.height = y - g_rectangle.y;
}
}
break;
//左键按下消息
case EVENT_LBUTTONDOWN:
{
g_bDrawingBox = true;
g_rectangle = Rect(x, y, 0, 0);//记录起始点
}
break;
//左键抬起消息
case EVENT_LBUTTONUP:
{
g_bDrawingBox = false;//置标识符为false
//对宽和高小于0的处理
if (g_rectangle.width < 0)
{
g_rectangle.x += g_rectangle.width;
g_rectangle.width *= -1;
}
if (g_rectangle.height < 0)
{
g_rectangle.y += g_rectangle.height;
g_rectangle.height *= -1;
}
//调用函数进行绘制
DrawRectangle(image, g_rectangle);
}
break;
}
}
//-----------------------------------【DrawRectangle( )函数】------------------------------
// 描述:自定义的矩形绘制函数
//-----------------------------------------------------------------------------------------------
void DrawRectangle(cv::Mat& img, cv::Rect box)
{
cv::rectangle(img, box.tl(), box.br(), cv::Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)));//随机颜色
}
鼠标操作还是不是很理解。
Mat这个类
其中:CV_8UC3表示,8位无符号三通道(三通道就是每个像素由3个元素组成)
CV-【位数】【是否带位数】C【通道数】
Scalar是一个short型向量
我还是不会用,这个到底那个参数对应的那个变量呢?
而Scalar()是表示颜色的一个类
Scalar(a,b,c)a,b,c分别为c为红色分量,b是绿色分量,a是蓝色分量
Rect()表示矩形,他的成员变量主要X,Y,width,height
cvtColor()函数表示颜色空间转换,可以实现RGB颜色向HSV,HSI等颜色空间的转换,也可以转换成灰度图像,只是参数不同
下面的部分主要是一些在opencv中绘制图像的方法:
问题发现,这里面东西好多,那么多参数,
point()函数表示点这个类,
用于绘制直线用line()函数
用于绘制椭圆额函数ellipse()函数
用于绘制矩形的函数circle()函数
用于绘制填充多边形的fillpoly()函数
然后浅墨在书中自定义了几个函数,用来绘制不同尺度的椭圆
计时函数getTickCount()函数和getTickFrequency()函数
让我对创造进度条函数有了一定的理解。
dft()函数字一维或者二维数组进行正向或者反向的傅里叶变换
浅墨这里的例子只能变换二维数组,也就是说这里的图像都是灰色的,如果换成彩色图片是不可以的。
输出可扩展识别语言xml;
还讲了一些输入输出的语言的方式。
回调函数这部分不懂,但是效果图是出来的。
绝对美!
第七篇:主要是讲的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 );
在这里介绍一下腐蚀操作:
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
int main()
{
Mat srcImage=imread("1.jpg");
imshow("原始图像",srcImage);
Mat element=getStructuringElement(MORPH_RECT,Size(5,5));
Mat dstImage;
erode(srcImage,dstImage,element);//src:原图像。dst:目标图像。element:腐蚀操作的内核。 如果不指定,默认为一个简单的 bubuko.com,布布扣 矩阵。否则,我们就要明确指定它的形状,可以使用函数getStructuringElement().
imshow("腐蚀后图",dstImage);
waitKey(0);
return 0;
}
均值滤波:
调用函数的格式更加简单
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 )
第15篇
漫水填充法是一种用特定的颜色填充联通区域,通过设置可连通像素的上下限以及连通方式来达到不同的填充效果的方法。漫水填充经常被用来标记或分离图像的一部分以便对其进行进一步处理或分析,也可以用来从输入图像获取掩码区域,掩码会加速处理过程,或只处理掩码指定的像素点,操作的结果总是某个连续的区域。
floodFill 函数
int floodFill(InputOutputArray image, InputOutputArray mask, Point seedPoint,Scalar newVal, Rect* rect=0, Scalar loDiff=Scalar(), Scalar upDiff=Scalar(), int flags=4 )
用了浅墨的代码感觉无效。
第16章
在图像处理和与计算机视觉领域,兴趣点(interest points),或称作关键点(keypoints)、特征点(feature points) 被大量用于解决物体识别,图像识别、图像匹配、视觉跟踪、三维重建等一系列的问题。我们不再观察整幅图,而是选择某些特殊的点,然后对他们进行局部有的放矢的分析。如果能检测到足够多的这种点,同时他们的区分度很高,并且可以精确定位稳定的特征,那么这个方法就有使用价值。像特征类型可以被分为如下三种:
<1>边缘
<2>角点 (感兴趣关键点)
<3>斑点(Blobs)(感兴趣区域)
cornerHarris 函数用于在OpenCV中运行Harris角点检测算子处理图像。
void cornerHarris(InputArray src,OutputArray dst, int blockSize, int ksize, double k, intborderType=BORDER_DEFAULT
函数Threshold( ) 对单通道数组应用固定阈值操作。该函数的典型应用是对灰度图像进行阈值操作得到二值图像。(另外,compare( )函数也可以达到此目的) 或者是去掉噪声,例如过滤很小或很大象素值的图像点。
double threshold(InputArray src,OutputArray dst, double thresh, double maxval, int type)
浅墨这里写的吧,不是太好做,系统直接崩盘了
第17篇,讲的重映射
emap( )函数会根据我们指定的映射形式,将源图像进行重映射几何变换
void remap(InputArray src, OutputArraydst, InputArray map1, InputArray map2, int interpolation, intborderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
为什么我的图片是上下颠倒?而浅墨的左右颠倒?懂了,remap这个函数只能实现X轴的对称旋转,浅墨那里放图错了
实现Harris角点检测的coreHarris()函数
SURF特征点检测:
drawKeypoints函数
void drawKeypoints(const Mat&image, const vector<KeyPoint>& keypoints, Mat& outImage, constScalar& color=Scalar::all(-1), int flags=DrawMatchesFlags::DEFAULT )
第18篇
仿射变换:仿射变换(Affine Transformation或 Affine Map),又称仿射映射,是指在几何中,一个向量空间进行一次线性变换并接上一个平移,变换为另一个向量空间的过程。
仿射变换来表示如下三种常见的变换形式:
旋转,rotation (线性变换)
平移,translation(向量加)
缩放,scale(线性变换)
相关函数:warpAffine函数:
void warpAffine(InputArray src,OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, intborderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
getRotationMatrix2D函数:
好吧,第一步,就这样囫囵吞枣的学完了!
下面对照着女神的安排,实现对摄像头的调用
opencv
效果图:
从摄像头中采集视频
#include <opencv2\\highgui\\highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char **argv)
{
VideoCapture cap(0);
if (!cap.isOpened())
{
cout << "不能打开摄像头!" << endl;
return -1;
}
double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH);
double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
cout << "视频帧尺寸 : " << dWidth << " x " << dHeight << endl;
namedWindow("MyVideo", CV_WINDOW_AUTOSIZE);
while (1)
{
Mat frame;
bool bSuccess = cap.read(frame);
if (!bSuccess)
{
cout << "不能从视频流中读取帧!" << endl;
break;
}
imshow("MyVideo", frame);
if (waitKey(30) == 27)
{
cout << "ESC键被按下" << endl;
break;
}
}
waitKey(0);
return 0;
};
对照浅墨大神的书,然后在这里做出一些补充:
边缘检测:
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
int main()
{
Mat srcImage=imread("1.jpg");
imshow("原始图",srcImage);
Mat edge,grayImage;
cvtColor(srcImage,grayImage,CV_BGR2BGRA);//将输出的图像转换成灰度图像
blur(grayImage,edge,Size(3,3));//使用3*3的内核来进行消噪
Canny(edge,edge,3,9,3);运行canny算子
imshow("效果图",edge);
waitKey(0);
return 0;
}
效果图:
利用opencv读取视频:
效果图:
视频是读取出来了,但是就是没有声音
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
VideoCapture capture("1.avi");//读取视频
while (1)//利用while循环显示每一帧的因素
{
Mat frame;
capture>>frame;//读取当前帧的视频
imshow("读取的视频",frame);//显示当前帧
waitKey(30);//延迟30毫秒
}
return 0;
}
如果把
VideoCapture capture("1.avi");//读取视频
改成:
VideoCapture capture(0);//就变成了读取摄像头的数据
效果图:
还可以在这个基础上,对摄像头调用到的数据进行canny边缘检测。
效果图
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
VideoCapture capture(0);
Mat edges;
while (1)
{
Mat frame;
capture>>frame;
cvtColor(frame,edges,CV_BGR2BGRA);//将输出的图像转换成灰度图像
blur(edges,edges,Size(7,7));//使用3*3的内核来进行消噪
Canny(edges,edges,0,30,3);
imshow("效果图",edges);
if(waitKey(30)>=0) break;
}
return 0;
}
原来opencv 的例子当中有那么多直接就可以用的程序
camshift:
然后程序的运行效果:
我感觉像是人脸识别的,具体用法是对鼠标选的的区域的颜色目标进行跟踪。但是这三个参数是什么意思,我还是没有搞清楚。
点追踪:
效果图:
点在脸上的几个点,会随着脸的运动而运动。
人脸识别的程序,没有图像,也不知道为什么
9月11号到今天9月14号,已经有一段时间了,继续开始opencv的知识吧,现在cmake中文安装路径的问题没有解决。
算了,先跳过这部分吧。
还有一些命名规范:属性名+类型+对象描述。
Src表示源对象,Dst表示目标对象
arg指的是参数,argc指的是整数 *argv[]表示的是字符串数组。printf,最后面的f表示“format格式”其功能是按照用户指定格式,把指定数据显示到窗口中。printf中的一些特殊规定符号:\\n换行操作,\\f清屏并换页,\\r回车,\\t Tab符。
2016年9月15日
还是下定决心解决cmake 的问题,在过程中,遇到很多问题,然后在VS的版本选择上,选了2013,因为毕竟有中文版的软件。昨天在安装的过程中遇到了,问题是,我当时直接默认了安装,结果全部都安装了,我百度了一下,如果中途取消安装的话,不好删除,也不好再安装,只能硬着头皮安装下去。整整花了2个多小时。
安装完以后C盘只有不到85G,感觉太少,而且系统缓慢。跟老王沟通了一下,还是决定重新安装,老王建议2015,我又开始安装2015,
这幅图是正确安装2013的需要选的功能,全部安装的话,大概需要1个小时左右吧。
跟老王商量后选的vs2015的安装软件:
然后安装以后C盘只有69G,我也不知道原因,而且,我装的2015不能汉化,我决定用系统还原节点的方法,还原后然后装VS2013。毕竟是中文版,但是在还原的过程中,还原后无法开机,无奈,重新装系统吧,重装了系统以后已经一个上午了,然后很多软件配置了一遍以后,开始装好了VS2013,启动还是很快的,至少比2010块很多。
显示的程序可以运行。因为我的电脑是64位操作系统,然后在新建了一个X64,(原来的X86表示的是32位操作系统),然后在X64上进行与win32一样的配置。
然后cmake也出现了问题,我跟浅墨用的一样的版本以后,发现没有2013的版本,然后我自己配置了一下,原理清楚:
camke的官网:http://www.cmake.org/
分水岭算法:
watershed函数
图像修补:
inpaint()函数,
计算直方图的函数:calcHist()函数:
绘制一唯的直方图:
绘制三维RGB的图像:
反映射:
模式匹配:就是在模糊的情况下也能够处理图像.
直到现在浅墨这本书基本上看完了。
2016年11月5日进行补充:
当时一直也没有写关于SURF的内容,最近因为要做高等工程数学的PPT,想讲这个内容,还是过来学习学习
代码部分:
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <opencv2/nonfree/nonfree.hpp>
#include<opencv2/legacy/legacy.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
system("color 1A");
Mat srcImage1 = imread("1.jpg", 1);
Mat srcImage2 = imread("2.jpg", 1);
//【2】使用SURF算子检测关键点
int minHessian = 700;//SURF算法中的hessian阈值
SurfFeatureDetector detector(minHessian);//定义一个SurfFeatureDetector(SURF) 特征检测类对象
std::vector<KeyPoint> keyPoint1, keyPoints2;//vector模板类,存放任意类型的动态数组
//【3】调用detect函数检测出SURF特征关键点,保存在vector容器中
detector.detect(srcImage1, keyPoint1);
detector.detect(srcImage2, keyPoints2);
//【4】计算描述符(特征向量)
SurfDescriptorExtractor extractor;
Mat descriptors1, descriptors2;
extractor.compute(srcImage1, keyPoint1, descriptors1);
extractor.compute(srcImage2, keyPoints2, descriptors2);
//【5】使用BruteForce进行匹配
// 实例化一个匹配器
BruteForceMatcher< L2<float> > matcher;
std::vector< DMatch > matches;
//匹配两幅图中的描述子(descriptors)
matcher.match(descriptors1, descriptors2, matches);
//【6】绘制从两个图像中匹配出的关键点
Mat imgMatches;
drawMatches(srcImage1, keyPoint1, srcImage2, keyPoints2, matches, imgMatches);//进行绘制
//【7】显示效果图
imshow("匹配图", imgMatches);
waitKey(0);
return 0;
}
遇到的问题:在opencv3下是不能进行surf,因为少了一个控件,这个控件在opencv 因为收费问题,就不能加,所以,只能用opencv2系列的版本,我的版本是opencv2.13
以上是关于[opencv]学习之路的主要内容,如果未能解决你的问题,请参考以下文章
[原创]java WEB学习笔记61:Struts2学习之路--通用标签 property,uri,param,set,push,if-else,itertor,sort,date,a标签等(代码片段