痛定思痛,还是决定要学习opencv,光学C++和MATLAB还是不够的,网上很多现成的图像方面的资源都是用opencv写的,不会opencv的话还得用MATLAB自己重新编,所以还是用opencv吧 听起来都比matlab高大上,matlab可以用来看看算法的效果,opencv才是主要工具。

参考http://blog.csdn.net/poem_qianmo/article/details/19925819他的开始学的

第一篇是配置opencv的环境

中间我出现过这样的问题:

后来把pic.jpg图片放到 C++文件即.cpp所在目录下

即和cpp文件同级目录下 再运行 就不会出现错误了 看:

这样就行了!

第二篇那位大师讲到的imwrite函数 我在上面显示出这个美女图后加上一句 :

imwrite("111.jpg",img);

发现它默认保存在cpp文件同级的目录中 不用特意指定目录

第四篇是ROI区域和线性混合

出现这样的错误

原来是两幅图的大小不一样 不能进行线性混合 之前的ROI区域就没这个限制 只要一幅图大一幅图小就行了

后来换成了两幅同样大小的图进行线性混合就没有error了

第五篇是分离颜色通道和混合多通道

分离时 弹出了一个错误 后来发现 原来是想叠加的那副小图载入时没有按灰度图像载入 少了个0

girl=imread("pic.jpg");
little=imread("wo.jpg",0);后来把0加上就行了 
vector<Mat> channels;

因为后面是把这个little的图片和某一个通道混合 所以它首先必须是按灰度图片读入的 这样就没error了

第六篇 滚动条和亮度值调整

滚动条照着浅墨的写 没出现error

亮度对比度也是照着他的写的 没出现error

第七篇是关于cmake的

第八篇是方框滤波,均值滤波和高斯滤波

第三部分没问题 第四部分利用trackbar调整内核值进行三种滤波时 我弹出问题:

这个不是载入图片时路径的问题 因为我加了句

girl=imread("pic.jpg");
if(!girl.data)
{
cout<<"damn!wrong in reading!"<<endl;
return -1;
}

事实是 这个图片在beautyprimer窗口还是显示出来了  所以证明还是读到了 因为我图片是放到了cpp同级目录下  我遇到的这个并不是网上说的路径读到是空的

是什么问题呢 之前前几课都显示得好好的

后来 结合浅墨之前写的 利用滚动条调整对比度和亮度的那个程序   我把这个改成了下面这样:就没有error了

#include<iostream>
#include"opencv2/core/core.hpp"  //原来这里打双引号或者尖括号都可以
#include"opencv2/highgui/highgui.hpp"  
#include"opencv2/imgproc/imgproc.hpp" 
using namespace std;
using namespace cv;
static void on_BoxFilter(int, void *);            //方框滤波  
static void on_MeanBlur(int, void *);           //均值滤波  
static void on_GaussianBlur(int, void *);                    //高斯滤波
Mat girl,g_dstImage1,g_dstImage2,g_dstImage3;  
int g_nBoxFilterValue=3;  //方框滤波参数值  
int g_nMeanBlurValue=3;  //均值滤波参数值  
int g_nGaussianBlurValue=3;  //高斯滤波参数值

static void on_BoxFilter(int, void *)  
{   
  namedWindow("beautyprimer",1);
       boxFilter(girl, g_dstImage1, -1,Size( g_nBoxFilterValue+1, g_nBoxFilterValue+1)); 
  imshow("beautyprimer",girl);
       imshow("【<1>方框滤波】", g_dstImage1);  
}  
static void on_MeanBlur(int, void *)  
{    
  namedWindow("beautyprimer",1);
       blur(girl, g_dstImage2, Size( g_nMeanBlurValue+1, g_nMeanBlurValue+1),Point(-1,-1));    
  imshow("beautyprimer",girl);
       imshow("【<2>均值滤波】", g_dstImage2);  
}  
static void on_GaussianBlur(int, void *)  
{   
  namedWindow("beautyprimer",1);
       GaussianBlur(girl, g_dstImage3, Size( g_nGaussianBlurValue*2+1,g_nGaussianBlurValue*2+1 ), 0, 0);  
  imshow("beautyprimer",girl);
       imshow("【<3>高斯滤波】", g_dstImage3);  
}

int main()
{
system("color 5F");
girl=imread("pic.jpg");
if(!girl.data)
{
cout<<"damn!wrong in reading!"<<endl;
return -1;
}

g_dstImage1= Mat::zeros( girl.size(), girl.type() );
g_dstImage2= Mat::zeros( girl.size(), girl.type() );
g_dstImage3= Mat::zeros( girl.size(), girl.type() );

namedWindow("【<1>方框滤波】",1);
createTrackbar("内核值:", "【<1>方框滤波】",&g_nBoxFilterValue, 40,on_BoxFilter ); 
    on_BoxFilter(g_nBoxFilterValue,0);

namedWindow("【<2>均值滤波】" ,1);
    createTrackbar("内核值:", "【<2>均值滤波】",&g_nMeanBlurValue, 40,on_MeanBlur ); 
on_MeanBlur(g_nMeanBlurValue,0);

namedWindow("【<3>高斯滤波】", 1);
createTrackbar("内核值:", "【<3>高斯滤波】",&g_nGaussianBlurValue, 40,on_GaussianBlur ); 
on_GaussianBlur(g_nGaussianBlurValue,0);

while(char(waitKey(1))!= 'q') {} 
return 0;
}

结果:

这样就没有error了 至于之前为什么有 我还不知道 等学习到后面应该就明白了  反正改成这样出来结果是正确的

我后来又试了下 如果把回调函数的最后一句放在主函数里 即createTrackbar的后面  结果可以显示出来 但鼠标移动内核值时 图片没变化 也就是没刷新 就像有些网友说的 imshow放在回调函数里有刷新的作用 不能放在主函数里  不然图片就是个“死”的

刚刚我吃完饭 又试了下 发现imshow可以放在main函数里  只要像浅墨写的那样把原图clone给结果图 也就是:

.......(声明部分和前面一样)

static void on_BoxFilter(int, void *)  
{   
       boxFilter(girl, g_dstImage1, -1,Size( g_nBoxFilterValue+1, g_nBoxFilterValue+1)); 
  imshow("beautyprimer",girl);
  imshow("【<1>方框滤波】",g_dstImage1);
}  
static void on_MeanBlur(int, void *)  
{    
       blur(girl, g_dstImage2, Size( g_nMeanBlurValue+1, g_nMeanBlurValue+1),Point(-1,-1));    
  imshow("beautyprimer",girl);
       imshow("【<2>均值滤波】", g_dstImage2);  
}  
static void on_GaussianBlur(int, void *)  
{   
       GaussianBlur(girl, g_dstImage3, Size( g_nGaussianBlurValue*2+1,g_nGaussianBlurValue*2+1 ), 0, 0);  
  imshow("beautyprimer",girl);
       imshow("【<3>高斯滤波】",g_dstImage3); 
}

int main()
{
system("color 5F");
girl=imread("pic.jpg");
if(!girl.data)
{
cout<<"damn!wrong in reading!"<<endl;
return -1;
}

namedWindow("beautyprimer",1);
imshow("beautyprimer",girl);

g_dstImage1= girl.clone( );  
       g_dstImage2= girl.clone( );  
       g_dstImage3= girl.clone( );

namedWindow("【<1>方框滤波】",1);
createTrackbar("内核值:", "【<1>方框滤波】",&g_nBoxFilterValue, 40,on_BoxFilter ); 
    on_BoxFilter(g_nBoxFilterValue,0); 
imshow("【<1>方框滤波】",g_dstImage1);

namedWindow("【<2>均值滤波】" ,1);
    createTrackbar("内核值:", "【<2>均值滤波】",&g_nMeanBlurValue, 40,on_MeanBlur ); 
on_MeanBlur(g_nMeanBlurValue,0);
imshow("【<2>均值滤波】", g_dstImage2);

namedWindow("【<3>高斯滤波】", 1);
createTrackbar("内核值:", "【<3>高斯滤波】",&g_nGaussianBlurValue, 40,on_GaussianBlur ); 
on_GaussianBlur(g_nGaussianBlurValue,0);
imshow("【<3>高斯滤波】",g_dstImage3);

while(char(waitKey(1))!= 'q') {} 
return 0;
}

这样也可以 出来结果是可以调节的  这才是浅墨写的 之前我把clone的那三句看掉了  所以改成了上一种方法那样子  不过上一种和这种都可以 !

第九篇:非线性滤波(中值滤波和双边滤波) 没出现error

第十篇:膨胀和腐蚀

前一部分单独实现膨胀腐蚀没出现error 但后部分利用Trackbar在膨胀/腐蚀之前切换那里出现error  (因为我不是完全按照浅墨的写的 我是边看他写的边参照他前几课讲的自己试的  比如他这里在写main函数  那我就先不看 先自己根据前面的知识自己写一个main函数  看怎么样  所以并不是说他的有问题  相反 他写得很好)

......(声明部分略)

void Process()  
{  
       //获取自定义核  
       Mat element = getStructuringElement(MORPH_RECT, Size(2*g_nStructElementSize+1,2*g_nStructElementSize+1),Point( g_nStructElementSize, g_nStructElementSize ));    
       if(g_nTrackbarNumer== 0) 
           erode(yingtao,g_dstImage, element);   
       else
           dilate(yingtao,g_dstImage, element);   
       imshow("【效果图】", g_dstImage);  
}  
void on_TrackbarNumChange(int, void *)  
{  
       //腐蚀和膨胀之间效果已经切换,回调函数体内需调用一次Process函数,使改变后的效果立即生效并显示出来  
       Process();  
}  
    
void on_ElementSizeChange(int, void *)  
{  
       //内核尺寸已改变,回调函数体内需调用一次Process函数,使改变后的效果立即生效并显示出来  
       Process();  
}

int main()
{
Mat yingtao=imread("pic.jpg");
if(!yingtao.data)
{
cout<<"damn!wrong in reading!"<<endl;
return -1;
}
namedWindow("xiaowanzi",1);
imshow("xiaowanzi",yingtao);

g_dstImage=yingtao.clone();
namedWindow("【效果图】",1);
createTrackbar("dilate与erode切换","【效果图】",&g_nTrackbarNumer, 1, on_TrackbarNumChange);
createTrackbar("内核尺寸", "【效果图】",&g_nStructElementSize, 21, on_ElementSizeChange);  
Process();
on_TrackbarNumChange(g_nTrackbarNumer, 0);
on_ElementSizeChange(g_nStructElementSize, 0);
imshow("【效果图】",g_dstImage);

while(char(waitKey(1))!= 'q') {}
return 0;
}

这样子 按照前几课的 创建滚动条 再回调函数 再显示  不行 出现error如下:

把这句加上去 以后  还是弹出一样的error

Mat element = getStructuringElement(MORPH_RECT, Size(2*g_nStructElementSize+1,2*g_nStructElementSize+1),Point( g_nStructElementSize, g_nStructElementSize ));

我也不知道为什么  反正看来像原来那样创建Trackbar不行  后来我完全按照浅墨的写  把g_dstImage=yingtao.clone();也跟他一样不要(其实我很好奇为什么不要  发现加上这句和不加这句一样的  为什么前几课要加呢) 先把原图腐蚀一次 再创建Trackbar 然后就结束 结果:

的确貌似是可以了  可是我一移动滚动条 解弹出和上一次一样的error:

为什么会这样

经过提醒 我终于知道哪里错了 真想戳瞎我的铝合金狗眼  载入图片时多写了一个Mat

Mat yingtao=imread("pic.jpg");这句不能加Mat 如果加了Mat 那么后面滚动条读的yingtao的图片就不是我刚刚载入的樱桃小丸子 而是全局变量中的那个空的yingtao 所以移动滚动条时才会有错误  所以把Mat去掉就行了 这样全局变量的yingtao和我载入的yingtao就是同一张图片了  结果如下:

这是腐蚀的  下面是膨胀的 只需在全局变量那里把0改成别的数字就行 了并不一定要像浅墨所说改成1  我改成了2 结果:

不过我还是有个小疑惑 为什么加不加上

g_dstImage=yingtao.clone();
以及后面的回调函数:
//on_TrackbarNumChange(g_nTrackbarNumer,0);
    //on_ElementSizeChange(g_nStructElementSize,0);
//imshow("【效果图】",g_dstImage);
为什么加不加上这几句 结果都没影响 既然没影响 那之前几课中怎么加和不加就有影响呢???

第十一篇 开闭运算顶帽黑帽操作 梯度  没出现error

第十二篇 各种边缘检测的算子  也没有error

第十三篇 高斯金字塔 laplace金字塔 和resize  也没有出现error

可是有个小疑惑  最后一个综合实例里 while(1)循环里 key=waitKey(9) ;//读取键值到key变量中

是不是while(1)始终表示读取user输入的信息 就像C++里的while(cin)一样  对吗?可是while(cin)是在输入结束后 按下enter或者ctrl+d或者ctrl+z就自动截止这个while(cin)了  而opencv里的while(1)却只能在循环里把终止条件写出来 然后user根据终止条件才能终止?

key=waitKey(9) ;这句  之前几课用到waitKey(0)或者waitKey(5000)等 表示的是等待5000ms自动关闭窗口 或者是一直显示窗口 知道user手动关闭  可是这里的waitKey(9)是指读入user按键的ASCII值?(9)这个数是特定的吗?

第十四篇 霍夫变换 线检测和圆检测   没有error

也有个小疑惑  最后一个综合示例里 创建Trackbar 回调函数后 为什么还要调用一次HoughLinesP函数 HoughLinesP(g_midImage, g_lines, 1, CV_PI/180, 80, 50, 10 ); imshow("【效果图】", g_dstImage); 回调函数里不是已经有HoughLinesP函数了吗 我发现把这两句删掉也没事啊 出来效果是一样的

还有一个感慨  opencv里好多都会让人想到C++  像这篇文章里的vector容器啊 还有之前的while,,,case,,,啊  真的C++感觉像是opencv的零件一样  还有imshow这些imwrite这些就让人想起matlab

感觉C++就像是一部车的所有零件  对于做图像的人来说 matlab就像是自动档的车 很方便简捷 可是无法体现技术卓越  opencv就像是手动档的车  那些玩赛车的人表演技术都是用的手动档

第十五篇 漫水填充法 也没有error

但是这篇我没太理解 不过和我的研究方向没太大关系  所以这篇就pass过了

第十六篇  Harris角点检测  没有error

但这篇的很多函数不熟悉   估计是OpenCV语法上的  这篇和我的研究方向紧密相关   研究研究。。。

第十七篇 重映射与surf特征点检测  没有error

这篇在鱼眼图像拼接 全景漫游很有用

第十八篇  仿射变换与surf特征点匹配  没有error

对我很有用   虽然有的语法部分之前没见过  觉得很新奇

另外  昨天买的浅墨的《OpenCV3》终于今天下午到了   虽然贵了点  但计算机类的书都这么贵  也都比较厚  就像《C++ primer》一样  但还是好开心  准备开始啃了。。。

今天都9月11号了 刚刚和王志周童鞋讨论了下学OpenCV的问题  因为我十天看完了OpenCV3  然后这些天一直忙着开学交通信作业 真不知道我学图像的偏偏叫我们开通信的课是什么意思  然后又是把之前没弄出来的鱼眼校正的程序重新写调试 还是用MATLAB写的  还不敢用OpenCV写 因为基础语法还有很多不知道  现在看完那本书只是基本上能看懂opencv写的程序。。。所以OpenCV的学习又中断了快20天了  我怕自己忘记  然后刚刚讨论了下 还上网查了下  发现不能中断 哪怕一天只学一小会 或者隔天学一会也行  他说这个是积累的  :

D:\myopencv\opencv\build\doc这个目录下  opencv_cheatsheet.pdf 以及opencv_tutorials.pdf以及opencv_user.pdf对自学很有帮助  王志周大盆友说opencv_tutorials.pdf看第二章到第四章就行了

D:\myopencv\opencv\sources\samples\cpp这个目录下 也是利于自学的  可以在看完opencv_tutorials.pdf那三章后就看这个

别人说学OpenCV可以先把这些官方示例先运行 然后逆向推导作者的编程思路步骤 然后再看代码 分析与自己之前想象的思路比较  再次形成自己的思路步骤 然后再抛开现成代码 自己写一次 最后再比较

不过这个好像还不适合我  我是先分析现有代码 然后再运行 然后在自己看第一遍时有问题的地方 改成自己认为的样子 看运行出来是怎样  或者看有的代码时候比较熟悉就自己试着写 然后运行 如果有错 就与现成代码对比 找原因 如果没错 就与现成代码比较 看哪里不同 作者为什么不像我一样写而选择他那样

等我学完这些再来讲体会

OpenCV学习之路相关推荐

  1. OpenCV学习之路(附加资料分享)

    目录 一.前言 二.学习历程 三.学习资料 书籍 网站 视频教程 四.学习建议 入门 强化 灵通 一.前言 有人问我,学习opencv从哪里学起?有人问我,我学习opencv用到了哪些资料?所以在今天 ...

  2. 【OpenCV 学习之路】(8)数独提取之一

    写在前面: 关于本次的数独识别项目,我先说明下情况: 这是本人18年6月份做的,现在把当时的笔记整理出来(口吻的描述是以当时的时间来描述). 这个数独的项目分别做了两次, 第一次做的还没做完,第二次可 ...

  3. Opencv 学习之路(一)

    前面很长一段时间一直在用opencv库但是一直没有去系统的学习,都是遇到问题直接百度,连库内大多数函数都不认识.最近闲下来了打算系统将opencv学习下 1.打开图片 2.读取视频 3.打开摄像头拍照 ...

  4. OpenCV学习之路之OpenCV安装(VS2013版)

    开始学习OpenCV,首先就是成功的将OpenCV装载到电脑上. 版本选择的是目前官网上可以下载的2.4.13,我的vs版本是2013. 花了差不多四个小时的时间才算是安装加调试全部完成. http: ...

  5. Opencv 学习之路(一)cmake +vs2015+Opencv3.4

    目录 大佬的环境配置方案 遇到问题总结: 一.重新生成Opencv.sln项目报错 1. 重新安装Python 2. 给VS OPENCV.sln 添加Python36_d.lib的路径 2.1    ...

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

    一.简介 二.外接矩形的查找绘制 1 #include "opencv2/opencv.hpp" 2 using namespace cv; 3 void main() 4 { 5 ...

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

    一.模板匹配概念 二.单模板匹配 1 #include "opencv2/opencv.hpp" 2 #include <iostream> 3 using names ...

  8. 创建mat二值图 matlab,OpenCV学习之路(二)——Mat对象

    早期的 OpenCV 中,使用 IplImage 和 CvMat 数据结构来表示图像.IplImage和 CvMat 都是 C 语言的结构.使用这两个结构的问题是内存需要手动管理,开发者必须清楚的知道 ...

  9. openCV学习之路(2-1)---深度解析imread函数

    代码如下: #include <iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/ ...

最新文章

  1. 软件项目质量保证——编码规范
  2. [ATF]-ATF启动--BL31跳转到optee和uboot
  3. Go 语言框架 Gin 练习2
  4. [Objective-C语言教程]动态绑定(32)
  5. git/github使用完整教程(1)基础
  6. Be My Eyes app:我是你的眼
  7. Redis面试 - redis 的雪崩和穿透?
  8. python两个 list 获取交集,并集,差集的方法
  9. layoutSubview 总结
  10. 吴恩达机器学习笔记23-神经网络:表述--非线性假设(Non-linear Hypotheses)
  11. 【Spring-AOP】底层类AbstractAutoProxyCreator分析
  12. tftp工具_tftp,tftp等八款最佳的FTP客户端工具
  13. Python语法糖系列
  14. mysql人脸数据库_人脸数据库汇总
  15. 数据库管理系统的概念及数据库管理系统的基本功能
  16. Redis和MySQL如何保持数据一致性
  17. python关于q检验
  18. pymol作图-设置label的字体
  19. 输入直角三角形的两个直角边的长度 a、b,求斜边 c 的长度。
  20. 中国市场 Android App 兼容性报告

热门文章

  1. matlab怎么输入二维数组,MATLAB二维数组(矩阵)的创建
  2. Shell脚本语法3.21
  3. Big-endian
  4. 聚簇索引和非聚簇索引(通俗易懂 言简意赅)
  5. 50个极具创意和灵感的404页面
  6. 麦积机器人_天水市一中麦积校区师生在“青少年机器人竞赛”活动中再创佳绩...
  7. STAR-CCM+ 二维翼型模拟
  8. 版式文件 流式文件_画册版式设计的重要性!
  9. 【分享】后厂村鲜为人知的另一面
  10. delphi源码 中间件 框架【网盘映射】