OpenCV尝试心得

opencv使用心得

前言

opencv是一款计算机视觉库,初次接触计算机视觉感觉计算机视觉有点东西 -.-,很多的图像处理之间的关系需要我们对图像的知识。

图像

以前没接触过图像,自己认为的图像就是屏幕上RGB的像素点,每个像素点,是图像的一开始的状态,但是通过这次培训明白了图像是RGB三层像素之间的叠加,取样频率和量化之间的概念,在我理解看来也就是RGB的不同颜色之间像素深度的一个叠加,其实屏幕上的图像在内存中也是以像素深度数值来进行表示,如图:
OpenCV尝试心得

图像的傅里叶变化

以下内容引自:https://www.cnblogs.com/tenderwx/p/5245859.html
如有侵权请立即与我联系,我将及时处理

图像的频率是表征图像中灰度变化剧烈程度的指标,是灰度在平面空间上的梯度。如:大面积的沙漠在图像中是一片灰度变化缓慢的区域,对应的频率值很低;而对于地表属性变换剧烈的边缘区域在图像中是一片灰度变化剧烈的区域,对应的频率值较高。傅里叶变换在实际中有非常明显的物理意义,设f是一个能量有限的模拟信号,则其傅里叶变换就表示f的频谱。从纯粹的数学意义上看,傅里叶变换是将一个函数转换为一系列周期函数来处理的。从物理效果看,傅里叶变换是将图像从空间域转换到频率域,其逆变换是将图像从频率域转换到空间域。换句话说,傅里叶变换的物理意义是将图像的灰度分布函数变换为图像的频率分布函数。
傅里叶逆变换是将图像的频率分布函数变换为灰度分布函数傅里叶变换以前,图像(未压缩的位图)是由对在连续空间(现实空间)上的采样得到一系列点的集合,通常用一个二维矩阵表示空间上各点,记为z=f(x,y)。又因空间是三维的,图像是二维的,因此空间中物体在另一个维度上的关系就必须由梯度来表示,这样我们才能通过观察图像得知物体在三维空间中的对应关系。
傅里叶频谱图上我们看到的明暗不一的亮点,其意义是指图像上某一点与邻域点差异的强弱,即梯度的大小,也即该点的频率的大小(可以这么理解,图像中的低频部分指低梯度的点,高频部分相反)。一般来讲,梯度大则该点的亮度强,否则该点亮度弱。这样通过观察傅里叶变换后的频谱图,也叫功率图,我们就可以直观地看出图像的能量分布:如果频谱图中暗的点数更多,那么实际图像是比较柔和的(因为各点与邻域差异都不大,梯度相对较小);反之,如果频谱图中亮的点数多,那么实际图像一定是尖锐的、边界分明且边界两边像素差异较大的。
对频谱移频到原点以后,可以看出图像的频率分布是以原点为圆心,对称分布的。将频谱移频到圆心除了可以清晰地看出图像频率分布以外,还有一个好处,它可以分离出有周期性规律的干扰信号,比如正弦干扰。一幅频谱图如果带有正弦干扰,移频到原点上就可以看出,除了中心以外还存在以另一点为中心、对称分布的亮点集合,这个集合就是干扰噪音产生的。这时可以很直观的通过在该位置放置带阻滤波器消除干扰。

在我个人理解的观点,傅里叶变换将图像在空间一点的像素点的变换转换为频率关系,从而利用频率之间的关系来对图像进行处理,个人观点,如有谬误,希望大家指正批评。

边缘检测

我们已知的图像是在平面上由数字组成的矩阵,在我个人理解来说
如图:
OpenCV尝试心得
这个穿着黑色风衣的帅气男子,现在假设用一个矩阵来表示这个图像为:
OpenCV尝试心得
(excel画图不太美观。。。。)
我们可以假设周围背景的像素深度变化比较均匀(这里用0来进行表示),可见在该矩阵中在边界处,这张图片的像素变化比较大,通过检测图像的像素升降的缓急,(也可以认为是数学中的导数大小)来确定哪几个点为图像的边界,从而计算出图像的边界部分,(当然实际应用中这些算法很复杂)

图像的锐化和平滑

个人理解:
图像的锐化:即增强图像中边界部分,从而凸显出图像中的物体的边缘,使图像中的物体更加凸显。
图像的平滑:即减弱图像中边界部分,将图形边界的变化减小。
OpenCV尝试心得
如图将边界数值增大即为图像的锐化处理,将图像边界的数值减小即为图像的平滑。

图像的高斯模糊

高斯模糊图片示例:
OpenCV尝试心得
其实现原理就是对图像进行平滑处理,但是如果高斯模糊的中心点到各个点的权值相同,这显然是不合理的,在我们的印象中应该是离中心点最近的点与中心点的灰度值大小可以近似,即距离中心点最近的点灰度值的权值更大,所以我们使用正态分布的分布函数来近似对图形中心点进行拟合。
计算过程如图所示:
OpenCV尝试心得
这种计算会导致外围一圈(55的卷积模板为横向缺失四行,纵向缺失四行,77卷积模板横向丢失六行,纵向丢失6行,以此类推)的图像无法进行卷积操作,需要后续进行优化操作。
实现如下:

#include <opencv2/opencv.hpp>
//#include <iostream>
using namespace std;
using namespace cv;
#define PI 3.1415926
int main(int argc,char ** argv)
{
	Mat src = imread("E:/lena.jpg", 1);			//读入目标图像
	cvtColor(src, src, COLOR_BGR2GRAY);			//转换颜色空间
	namedWindow("src", WINDOW_AUTOSIZE);		//原图像输出窗口
	imshow("src", src);							//显示载入图像

	//5x5卷积模板
	Mat model = Mat(5, 5, CV_64FC1);
	double sigma = 80;							//正态分布中的sigma值
	for (int i = -2; i <= 2; i++)				//此处通过两层循环来对卷积模板进行赋值
	{
		for (int j = -2; j <= 2; j++)
		{
			model.at<double>(i + 2, j + 2) =
				exp(-(i * i + j * j) / (2 * sigma * sigma)) /
				(2 * PI * sigma * sigma);
		}
	}

	double gaussSum = 0;
	gaussSum = sum(model).val[0];
	for (int i = 0; i < model.rows; i++)				//验证正态分布的模板是否最终和为0;
	{
		for (int j = 0; j < 5; j++)
		{
			model.at<double>(i, j) = model.at<double>(i, j) /
				gaussSum;
		}
	}

	Mat dst = Mat(src.rows - 4, src.cols - 4, CV_8UC1);

	for (int i = 2; i < src.rows - 2; i++)				//此处使用循环实现将卷积模板与原图像的灰度值进行卷积运算
	{
		for (int j = 2; j < src.cols - 2; j++)
		{
			double sum = 0;
			for (int m = 0; m < model.rows; m++)
			{
				for (int n = 0; n < model.cols; n++)
				{
					sum += (double)src.at<uchar>(i + m - 2, j + n - 2) *
						model.at<double>(m, n);
				}
			}

			dst.at<uchar>(i - 2, j - 2) = (uchar)sum;				//将卷积后的值赋值到图像

		}
	}

	namedWindow("gaussBlur", WINDOW_AUTOSIZE);			//定义输出窗口
	imshow("gaussBlur", dst);							//输出高斯模糊后的图像。

	waitKey(0);
	return 0;
}

效果如图(有点不明显):
OpenCV尝试心得
也可使用opencv自带函数进行高斯模糊操作

#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
#define PI 3.1415926
int main(int argc,char ** argv)
{
	Mat src = imread("E:/lena.jpg", 1);			//输入文件
	Mat dst = imread("E:/test3.jpg", 1);		//输出文件
	cvtColor(src, src, COLOR_BGR2GRAY);			//转换色彩空间
	namedWindow("src", WINDOW_AUTOSIZE);		//原图输出窗口
	imshow("src", src);							//输出原图
	GaussianBlur(src, dst, Size(15, 15), 80, 0);//高斯模糊函数
	namedWindow("dst", WINDOW_AUTOSIZE);		//输出窗口
	imshow("dst", dst);							//输出处理后的图片
	waitKey(0);
	return 0;
}

效果如下:
OpenCV尝试心得
感觉这次处理效果更好。

心得

通过这次实践,感觉自己对图形图像的一些知识加深了理解,感觉计算机视觉有点东西-.-,希望以后多接触这一方面东西,扩展自己的视野。
文章写的不太好,如果有谬误,希望大家批评指正,谢谢!