OpenCV从入门到放弃:摸鱼笔记(一)

    零cpp基础的小白探索OpenCV从从入门到放弃的摸鱼记录从这里开始。

    参考书:《OpenCV3编程入门》毛星云、冷雪飞 等编著 电子工业出版社

一、OpenCV(Open Source Computer Vision Library)开源计算机视觉库

    一个开源的机器视觉、图像处理的SDK(Software Development Kit / 软件开发工具包),支持C、C++、Python、Ruby等多种编程语言。

二、常用OpenCV头文件

    1、

OpenCV核心组件,核心功能模块。包含基本数据结构(如Mat、Rect等)、基本绘图操作、像素操作、ROI设置、图像混合、DFT(Discrete Fourier Transform)等

    2、

OpenCV图像处理组件。包括图像滤波、直方图、特征检测、图像变换等等

    3、

OpenCV高层GUI图形用户界面模块。包括图像载入、显示、写入、滑动条、鼠标操作等

    4、

此头文件定义包括以上三个在内的多个头文件,为了简化代码使用。本小白入门被建议不使用它。

三、OpenCV核心数据结构

1、Mat类

    OpenCV中图像储存的类,实为矩阵。由矩阵头(包括矩阵尺寸、存储方法、存储地址等信息)和一个指向存储所有像素的矩阵的指针两个部分组成。因此 Mat类在复制上有一个需要注意的点,赋值运算符和拷贝构造函数只复制信息头,并不复制图像本身储存信息。如

Mat A,C;
A = imread("1.jpg",CV_LOAD_IMAGE_COLOR);
Mat B (A); //拷贝构造函数
C = A;     //赋值运算符
以上A、B、C最终都指向同一个也是唯一一个数据矩阵。虽然信息头不同,但通过任何一个对象所做的改变也会影响其他对象。真想要复制应使用Mat的成员函数,如下

Mat F = A.clone();
Mat G;
A.copyTo(G);
这样使用,改变F或者G就不会影响Mat信息头所指向的矩阵了。

    Mat有多个非常有用的常用成员函数:

M.cols  返回矩阵列数

M.rows  返回矩阵行数

M.total()  返回矩阵元素数(不考虑多通道)

M.channels()  返回矩阵通道数

M.size()  以size类返回矩阵的尺寸

M.at  对矩阵元素进行访问

包括上面提及的.clone()和.copyTo等等,更多实用成员函数有待深入了解。

2、Point类

表示坐标中一个点的类型。Point2i和Point_等价于Point,整形的坐标点。用法:

//方法一
Point point;
point.x = 10;
point.y = 8;
//方法二
Point point = Point(10,8);

3、Scalar类

表示具有四个元素的数组,在OpenCV中用于传递像素值。

Scalar(a,b,c,d);
其中a、b、c分别表示BGR分量(就是反过来的),d表示alpha通道分量。

4、Size类

在OpenCV中用于表示尺寸的一个类,其两个重要的数据成员:width、heght 两个分表表示宽度和高度。

5、Rect类

表示一个矩形的类。成员变量有x、y、width、height分别表示左上角的点横坐标、纵坐标、矩形的宽度、高度。

Rect类常用的成员函数有:

rect.Size()  //返回矩形的尺寸

rect.area()  //返回矩形的面积

rect.contains(Point)  //判断点是否在矩形内

rect.inside(Rect)  //判断矩形是否在该矩形内

rect.tl  //返回左上角坐标

rect.br  //返回右下角坐标

矩形交集并集操作:

Rect rect = rect1 |  rect2;  //并集
Rect rect = rect1 & rect2;  //交集
矩形平移操作:

Rect rectShift = rect + point;
矩形缩放操作:

Rect rectScale = rect + size;

6、cvtColor()函数

颜色空间转换函数,使用格式:

cvtColor(inimg,outimg,CV_GRAY2BRG)
第一个参数为输入图像,第二个参数为输出图像,第三个参数为标识符,表示转换的目标颜色空间,查表可得。

四、第一个程序任务

任务:背景虚化功能。实时处理操作,圆圈外背景模糊,圆圈内保持清晰不变,圆圈位置和大小可以改变。

个人思路:鼠标操作确定圆心,满足在半径范围内的点像素值不变,其他的像素值用均值滤波后的数值替代。

#include 	 //OpenCV核心组件(Mat Point Rect etc.)
#include    //读写展示图像 、窗口组件
#include    //图像处理组件
#include                       //cin、cout头文件
#include                          //包含clock_t类头文件
using namespace cv;                      //指定OpenCV的命名空间
	
Mat img,temp;
int radius = 80,value = 5,k;  //初始化半径80个像素,平均滤波算子size为5
clock_t t1,t2;
void on_Trackbar(int,void*)  //滑条回调函数
{
	k = value;
}
Mat my_blur(int x,int y)  //圈外虚化处理函数
{
	Mat imgblur;	
	img.copyTo(imgblur);
	blur(img,imgblur,Size(k,k));
	//GaussianBlur(img,imgblur,Size(5,5),25,25);
	Point center(x,y);	  //定义点center 赋初值x,y
	for(int m = 1; m <= img.cols; m++)
		for (int n = 1; n <= img.rows; n++)  //m为列/x坐标,n为行/y坐标
		{ 
			if( ((m-x) * (m-x) + (n-y) * (n-y))<= (radius * radius))  //圈内用原像素值替换
			{
    //          imgblur.at(Point(m, n))[0] = temp.at(Point(m, n))[0]  ;  // B分量
    //          imgblur.at(Point(m, n))[1] = temp.at(Point(m, n))[1]  ;  // G分量(用法1) point(x坐标/列,y坐标/行)
    //          imgblur.at(Point(m, n))[2] = temp.at(Point(m, n))[2]  ;  // R分量
		imgblur.at(n,m)[0] = temp.at(n,m)[0]  ;  // B分量
                imgblur.at(n,m)[1] = temp.at(n,m)[1]  ;  // G分量(用法2)
                imgblur.at(n,m)[2] = temp.at(n,m)[2]  ;  // R分量
			}
		}
    circle(imgblur,center,radius,Scalar(255,255,255));//circle(图,圆心点(Point),半径,填充颜色(Scaler),线粗)画圆函数,线粗缺省默认为1
	return imgblur;
}
void function(int event,int x,int y, int flags, void* param)  //鼠标操作回调函数
{
	Point center = Point(x,y);    
	if ((flags & CV_EVENT_FLAG_CTRLKEY) && event == EVENT_LBUTTONDOWN)  //ctrl+左键,则半径+10后显示
	{
		t1 = clock();
		img.copyTo(temp);
		radius += 10;
		temp = my_blur(x,y);
		t2 = clock();					       //计时 clock()程序开始到调用次函数经过的计时单元数
		std::cout<<(double)(t2-t1)/CLOCKS_PER_SEC<

五、程序运行结果

OpenCV从入门到放弃:摸鱼笔记(一)_第1张图片

平均滤波模板8X8

OpenCV从入门到放弃:摸鱼笔记(一)_第2张图片

平均滤波模板20X20,明显变得更模糊

OpenCV从入门到放弃:摸鱼笔记(一)_第3张图片

平均滤波模板20X20,半径变大

OpenCV从入门到放弃:摸鱼笔记(一)_第4张图片

平均滤波模板20X20,半径变小









你可能感兴趣的:(openCV,opencv,常用类)