【新人励志贴】要求自己每天学习一小节opencv!!!
opencv吧
全部回复
仅看楼主
level 4
要求:
1. 每天学习一小节。
2. 需要有自己的见解,需要有自己的创新的特色的地方。
3. 多敲代码
4. 发散性思维
2017年05月16日 02点05分 1
level 4
前期准备:
1. 学习书籍为opencv3.(需要的自己百度,太多了)
2. 本人学习过c++,所以有一定的语言基础。
3. 使用opencv3的软体,opencv2从一代有了阶段性的飞跃,有全新的c++接口,而3代却是不同level的飞跃,采用了内核+插件的全新架构,标志着机器视觉的到来啦。
4. 现在搭配的是vs2010+opencv3.2.0
2017年05月16日 02点05分 2
level 4
1.基础知识见解
1.1 计算机视觉和机器视觉
https://www.zhihu.com/question/23183532这里有很详细的介绍。
我个人觉得嘛,既然都是视觉,学习了一样肯定会对另外一样的学习有帮助,所以不用那么纠结到底孰优孰劣,学什么好。
1.2 图像处理
图像处理主要针对三个方面(1.图像压缩、增强和复原。2.匹配。3.描述和识别)。数字化图像处理的对象是存放像素(灰度值)的二维数组。
1.3opencv
opencv包括两个内容,图像处理算法和计算机视觉算法。前者侧重“处理”图像,而后者则是使用计算机模拟人的视觉。
2017年05月16日 03点05分 3
level 4
2. opencv和vs2010环境配置
自行百度去,这里不做详细的介绍。不过收录一些我自己的问题,大家的问题也可以反馈给我,我总结后也放进来,供大家一起学习和解决。
2.1 目标程序x64和目标计算机x86冲突
2.1.1
在配置管理中将平台都设置为x64,运行即可。当然前提是你的文件目录那些没有弄错。
2.2 缺失msvcp140.dll
安装vc++2015的库即可。
2.3 我还遇到自己一个特别***的事,一直出现了异常未处理,查明原因后是内存溢出,但是我的图片有放在文件中啊,后来仔细看没有放对位置,需要放在与cpp同一目录下。
2017年05月16日 03点05分 4
level 4
3.简单程序上手了解
3.1图像腐蚀
算法介绍:将明亮的地方被暗的地方”腐蚀”掉。
算法作用:将一些小的噪声去除,一般都是和膨胀搭配使用。
原理:
选用一个模板,我们称之为结构元素,也就是定义什么样的像素被留下,什么样的像素被去除。
使用这个模板去处理图像,这个过程就是腐蚀。
如下图,手残党:
3.2 代码:
#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);
imshow("腐蚀",dstImage);
waitKey(0);
return 0;
}
3.3解析解析:
3.3.1http://blog.csdn.net/timidsmile/article/details/9135601头文件解释。
3.3.2Mat类
Mat类包括两个部分,一个是矩阵头(即包括矩阵的尺寸、存储方法、存储地址等信息)。还有一个是指向存储所有像素值得矩阵的指针。先大致了解下,暂时不去深究源码。
3.3.3erode腐蚀函数
我们使用了三个参数,第一个原图像,第二个是目标图像,第三个就是我们的结构元素啦,模板选的好,腐蚀的效果也会不一样。
2017年05月16日 03点05分 5
排版既然全不一样了,我恨,好吧,我自己看
2017年05月16日 03点05分
level 4
3.2均值模糊
3.2.1
算法作用:去除噪声的作用。
算法原理:均值滤波算法:在一个领域S中计算所有像素的平均灰度值,并替代需要处理的像素点。
缺点:首先,图像模糊了。其次,他是对所有的点都进行了同等对待,将噪声点分摊了也将图形边界点也分摊了。
改善:使用加权平均滤波。
噪声分两种:椒盐噪声和高斯噪声。前者位置随意,但是赋值相同。后者出现位置固定,但是幅值变化的。
中指滤波:将一个区域的所有灰度值进行排序,取位于中间灰度值替代需要处理的点。
3.2.2程序
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
int main(){
Mat srcImage = imread("1.jpg");
imshow("均值",srcImage);
Mat dstImage;
blur(srcImage,dstImage,Size(2,2));
imshow("滤波后",dstImage);
waitKey(0);
return 0;
}
2017年05月16日 04点05分 7
level 4
4. opencv滑动条
#include<opencv2/opencv.hpp>
using namespace cv;
#define WINDOW_NAME "线性混合示例"
const int g_nMaxAlphaValue = 100;
int g_nAlphaValueSlider;
double g_dAlphaValue;
double g_dBetaValue;
Mat g_srcImage1;
Mat g_srcImage2;
Mat g_dstImage;
void on_Trackbar( int, void* ){
g_dAlphaValue = (double) g_nAlphaValueSlider/g_nMaxAlphaValue;
g_dBetaValue = ( 1.0 - g_dAlphaValue );
addWeighted(g_srcImage1,g_dAlphaValue,g_srcImage2,g_dBetaValue,0.0,g_dstImage);
imshow( WINDOW_NAME, g_dstImage);
}
int main( int argc, char**argv ){
g_srcImage1 = imread("1.jpg");
g_srcImage2 = imread("2.jpg");
if( !g_srcImage1.data ){
printf("1error");
return -1;
}
if( !g_srcImage2.data ){
printf("2error");
return -1;
}
g_nAlphaValueSlider = 70;
namedWindow(WINDOW_NAME,1);
char TrackbarName[50];
//sprintf( "haha" );
printf( "hehe" );
sprintf( TrackbarName,"透明度 %d" ,g_nMaxAlphaValue );
createTrackbar( TrackbarName,WINDOW_NAME, &g_nAlphaValueSlider, g_nMaxAlphaValue, on_Trackbar );
on_Trackbar( g_nAlphaValueSlider, 0 );
waitKey(0);
return 0;
}
4.1 程序解析
4.1.1 addWeighted( src1, alpha, src2, beta, gama, dst);
src1、src2为原图像,并输出到dst上。
dst = alpha*src1+beta*src+gama
这个权重(alpha,beta)就是图片的Alpha通道,这个通道通过0-255的数值来代表该像素的透明度。
4.1.2
char TrackbarName[50];
sprintf( TrackbarName,"透明度 %d" ,g_nMaxAlphaValue );
格式化字符串,sprintf写将内容写入到字符串,而printf是写到命令行中的。
4.1.3 createTrackbar( TrackbarName,WINDOW_NAME, &g_nAlphaValueSlider, g_nMaxAlphaValue, on_Trackbar )
1参:滑动条的名字
2参:窗口名字
3参:滑动条的值的引用
4参: 滑动条的最大值
5参:回调函数,即不断更新画面的代码。
6参:void*是用户给回调函数的参数。若3是全局变量,则不需要。
2017年05月18日 06点05分 8
1.问题,为什么在createTrackbar中的滑动条的最大值为什么不用引用呢? 2.每当滑动条的值改变, 就会调用 on_trackbar 回调函数。既然调用了,为什么在尾部还需要在加一个on_trackbar的函数?
2017年05月18日 07点05分
level 4
5.鼠标画图
//------------------------【头文件、命名空间包含部分】--------------------------
// 描述:包含程序锁使用的头文件和命名空间
//--------------------------------------------------------------------------------
#include<opencv2/opencv.hpp>
using namespace cv;
#define WINDOW_NAME "程序窗口"
//--------------------------全局函数声明部分-------------------------------3
//---------------------------------------------------------------------------
void on_MouseHandle(int event, int x, int y, int flags, void *param);
void DrawRectangle( Mat& img, Rect box );
void showHelpText();
//--------------------------全局变量声明-----------------------------------
//
//-------------------------------------------------------------------------
Rect g_rectangle;
bool g_bDrawingBox = false;
//RNG g_rng(12345);
RNG g_rng((int)time(0));
//------------------------------main---------------------------------------
//
//--------------------------------------------------------------------------
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);
srcImage = Scalar(g_rng.uniform(0,255),g_rng.uniform(0,255),g_rng.uniform(0,255));
//2.
namedWindow( WINDOW_NAME );
setMouseCallback(WINDOW_NAME,on_MouseHandle,(void*)&srcImage);
//3.
while(1){
srcImage.copyTo(tempImage);
if( g_bDrawingBox ){
DrawRectangle( tempImage, g_rectangle );
}
//imshow( WINDOW_NAME, tempImage );
if( waitKey() == 27 ){
//break;
return 0;
}
//}
//return 0;
}
//-----------------------------on_MouseHandle()函数------------------------------
//
//--------------------------------------------------------------------------------
void on_MouseHandle( int event, int x, int y, int flags, void *param ){
Mat &image = *(Mat*) param;
switch( event ){
case EVENT_MOUSEMOVE:
{
if( g_bDrawingBox ){
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;
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 );
//imshow(WINDOW_NAME, image );
}
break;
}
}
//-------------------------DrawRectangle()------------------------
//
//----------------------------------------------------------------
void DrawRectangle( Mat& img, Rect box ){
//rectangle( img, box.tl(), box.br()-Point(1,1), Scalar( g_rng.uniform(0,255),g_rng.uniform(0,255),g_rng.uniform(0,255)));
rectangle( img, box, Scalar( g_rng.uniform(0,255),g_rng.uniform(0,255),g_rng.uniform(0,255)));
//rectangle( img, box, Scalar( g_rng(12345),g_rng(12345),g_rng(12345)));
//rectangle( img, box, Scalar( g_rng((int)time(0)),g_rng((int)time(0)),g_rng((int)time(0))));
}
5.1程序解析
5.1.1 CV_<bit_depth>(S|U|F)C<number_of_channels>
http://blog.csdn.net/maweifei/article/details/51221259
1--bit_depth---比特数---代表8bite,16bites,32bites,64bites---举个例子吧--比如说,如 如果你现在创建了一个存储--灰度图片的Mat对象,这个图像的大小为宽100,高100,那么,现在这张 灰度图片中有10000个像素点,它每一个像素点在内存空间所占的空间大小是8bite,8位--所以它对 应的就是CV_8 2--S|U|F--S--代表---signed int---有符号整形 U--代表--unsigned int--无符号整形 F--代表--float---------单精度浮点型 3--C<number_of_channels>----代表---一张图片的通道数,比如: 1--灰度图片--grayImg---是--单通道图像 2--RGB彩色图像---------是--3通道图像 3--带Alph通道的RGB图像--是--4通道图像
5.1.2
至于函数需要怎么使用,看这个库文件,查找就可以有很详细的说明
http://docs.opencv.org/3.2.0/d3/d63/classcv_1_1Mat.html#a626fe5f96d02525e2604d2ad46dd574f
5.1.3
2017年05月19日 05点05分 9
什么情况下,g_rectrangle.height<0 ? g_rectrangle.width<0?
2020年05月18日 10点05分
@大能猫😿 好吧,验证了下,起点往上往左画 对应着height<0 width<0
2020年05月18日 10点05分
level 4
续上楼鼠标画图事件:
疑问
1. 在main函数中,setMouseCallback并没有在循环语句当中,是不是只需要定义一次,在后面的运行中,只要触发了鼠标的事件就会直接运行setMouseCallback的回调函数?
2. 在while(1)当中,他又执行了一次DrawRectangle函数,如果按住了鼠标没放的话,那g_rectangle是一个有完整的数了,按理说应该会不断画,是srcImage.copyTo(tempImage)刷新了tempImage的画面起得效果是吧?
2017年05月19日 06点05分 10
level 3
然后楼主一个礼拜都没有坚持到...
2018年01月02日 11点01分 11
主要是排版太辛苦,而且每次排版完,简直不能直视。
2018年01月07日 15点01分
@子非秋刀鱼 嗯嗯,总之能学到东西就好,排版这个确实花时间,可以上传到github上,这个随意一点,或者csdn,排版快一点
2018年01月08日 01点01分
level 3
更啊
2018年01月10日 01点01分 13
level 2
Ss
楼主知道如何编程实现将一个mat型的矩阵以图片形式显示吗
2018年03月04日 10点03分 14
其实你就对一个mat型的图片形式进行初始化矩阵值就可以了啊,用imshow即可
2018年03月04日 13点03分
Ss
@子非秋刀鱼 这个矩阵是从文件读取得到的,不能自己初始化
2018年03月04日 14点03分
@Ss imshow函数就可以对mat输出图片
2018年03月05日 16点03分
Ss
楼主,对于一个灰度值全是200左右的矩阵,输出的图像都是黑点吗
2018年03月06日 11点03分
level 2
楼主还在吗?故事不够励志呀[笑眼]
2018年04月04日 09点04分 15
故事很鸡肋~
2018年04月06日 04点04分
@子非秋刀鱼 [笑眼][笑眼][笑眼]最近还在学吗?
2018年04月06日 12点04分
回复 学习啦🌐 :嘿嘿 我不是今天又更了一条么。。
2018年04月06日 14点04分
level 13
Yeah, big brother's got ideas.
2018年04月04日 11点04分 16
1 2 尾页