opencv 基础知识(二)

1、标量、向量

以下解释来自wiki

标量:又称纯量,是只有大小、没有方向、可用实数表示的一个量。实际上标量就是实数

向量:有大小、方向,在矩阵运算中,向量更多地被写成类似于矩阵的列向量或行向量。在线性代数中所指的向量,通常默认为列向量。
在这里插入图片描述

在opencv中,向量(矢量)用vec表示,eg:Vec<int ,3> vi (1,3,4);其实是个列向量。

2、图片的对比度、亮度、饱和度、锐化

对比度:
对比度指的是最高和最低灰度级之间的灰度差

亮度:
如果图像为灰度图,像素越低越暗,越高越亮

饱和度:
饱和度指的是图像颜色种类的多少,图像的颜色种类多,饱和度也就更高

锐化:
图像锐化是补偿图像的轮廓,增强图像的边缘及灰度跳变的部分,使图像变得清晰

梯度:
图像的梯度就是 G(x,y) = dx(i,j) + dy(i,j);
为x方向的增量和y方向的增量相加
一阶导数 :也就是图像的增量,反应的是图像像素的变化率
二阶导数:是一阶导数的增量,反应的是凹凸性

改变图像的对比度与亮度的有函数。

src.convertTo(des1, -1, 2.0, 50);
//目标图,深度值,透明通道(对比度),亮度

锐化有各种滤波。

3、图片的滤波与边缘填充(检测)
3.1、Canny边缘检测

步骤:灰度化-----》滤波------》canny;
canny内部实现,计算梯度幅值和方向------》.非极大值抑制-----》滞后阈值。进入源码一看,并不能看到这些实现的过程(看不懂是个原因)。

函数解析:第一个src,第二个out,第三个低阈值,第四个高阈值
阈值可以不分顺序,内部有交换函数

//源码在modules的opencv_imgproc模块下的canny.cpp ,有兴趣可以讨论。

//[1]第一种,全部交给内部函数处理
Mat image = imread("1.png");
Mat out;
Canny(image, out, 150, 30);

//[2]第二种。
//[2.1]灰度化
cvtColor(image, gray, COLOR_BGR2GRAY);
//[2.2]高斯降噪
blur(gray, edge, Size(3, 3));
//[2.3]canny 算子
Canny(edge, edge, 3, 9, 3);
3.2、Sobel算子

sobel算子,来计算一阶、二阶、三阶或混合图像差分。
详见:https://blog.csdn.net/poem_qianmo/article/details/25560901

函数解析:重点为第三个参数,这里可以取-1或者CV_16S等
在这里插入图片描述
//官方的代码 :先高斯滤波(降噪)或者 先转灰度图,然后进行边缘检测

//代码来自 毛星云
void SobelDetect()
{
	Mat grad_x, grad_y;
	Mat abs_grad_x, abs_grad_y, dst;
	//[1]载入原图
	Mat src = imread("1.png");
	imshow("sobel原图", src);
	//x方向的梯度
	Sobel(src, grad_x, CV_16S, 1, 0, 3); 
	
	**//当第三个参数为-1,就不需要转换成8位**
	
	convertScaleAbs(grad_x, abs_grad_x);
	//缩放,计算绝对值,然后将结果转换为8位。
	imshow("效果图2", abs_grad_x);

	//Y方向的梯度
	Sobel(src, grad_y, CV_16S, 0, 1, 3);
	convertScaleAbs(grad_y, abs_grad_y);
	imshow("效果图4", abs_grad_y);
	//合并显示
	addWeighted(abs_grad_y, 0.5, abs_grad_x, 0.5, 0, dst);
	imshow("合并图", dst);
}

同理其他的算子如:

  • Laplace,Laplacian 算子是n维欧几里德空间中的一个二阶微分算子
    Laplacian( src_gray, dst, CV_16S, 3);
  • Scharr,和sobel算子差不多,
    Scharr(src, dst, ddepth, dx, dy); 求dx;dy为0,dx为1;
    求dy;dx为0,dy为1;
3.3、霍夫变换(圆、线)

官方提出了两种方式划线
1、利用HoughLines

void HoughLinesDraw()
{
	//【1】载入原始图和Mat变量定义   
	Mat srcImage = imread("w.jpg");  //工程目录下应该有一张名为1.jpg的素材图
	Mat midImage, dstImage;//临时变量和目标图的定义

						   //【2】进行边缘检测和转化为灰度图
	Canny(srcImage, midImage, 50, 200, 3);//进行一此canny边缘检测
	cvtColor(midImage, dstImage,COLOR_GRAY2BGR);//转化边缘检测后的图为灰度图

											  //【3】进行霍夫线变换
	vector<Vec2f> lines;//定义一个矢量结构lines用于存放得到的线段矢量集合
	HoughLines(midImage, lines, 1, CV_PI / 180, 150, 0, 0);

	//【4】依次在图中绘制出每条线段
	for (size_t i = 0; i < lines.size(); i++)
	{
		float rho = lines[i][0], theta = lines[i][1];
		Point pt1, pt2;
		double a = cos(theta), b = sin(theta);
		double x0 = a*rho, y0 = b*rho;
		pt1.x = cvRound(x0 + 1000 * (-b));//不知道为什么
		pt1.y = cvRound(y0 + 1000 * (a));
		pt2.x = cvRound(x0 - 1000 * (-b));
		pt2.y = cvRound(y0 - 1000 * (a));
		line(dstImage, pt1, pt2, Scalar(55, 100, 195), 1,LINE_AA);
	}

	//【5】显示原始图  
	imshow("【原始图】", srcImage);

	//【6】边缘检测后的图 
	imshow("【边缘检测后的图】", midImage);

	//【7】显示效果图  
	imshow("【效果图】", dstImage);
	
	waitKey(0);
	return ;
}

2、利用HoughLinesP

void HoughLinesPDraw()
{
	//[1]载入原图
	Mat src = imread("w.jpg");
	Mat midImage, dstImage;
	//[2]进行边缘检测和转化灰度图
	Canny(src, midImage, 50, 200, 3);//进行一此canny边缘检测
	cvtColor(midImage,dstImage,COLOR_GRAY2BGR);//转化边缘检测后的图为灰度图
	//[3]霍夫变换
	vector<Vec4i> lines;
	HoughLinesP(midImage, lines, 1, CV_PI / 180, 80, 30, 10);
	//[4]划线
	for (size_t i = 0; i < lines.size(); i++)
	{
		Vec4i l = lines[i];
		line(dstImage, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 255, 255), 1);
	}
	//[5]显示原始图  
	imshow("【原始图】", src);

	//[6]边缘检测后的图 
	imshow("【边缘检测后的图】", midImage);

	//[7]显示效果图  
	imshow("【效果图】", dstImage);

}
4、图片的放大与缩小
  • resize函数
  • 高斯金字塔(缩小)
    //需要注意 金字塔必须是整数倍
  • 拉普拉斯金字塔(放大)
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值