一、opencv简述
Opencv(Open Source Computer Vision Library)是一个基于开源发行的跨平台计算机视觉库,它实现了图像处理和计算机视觉方面的很多通用算法,已成为计算机视觉领域最有力的研究工具。在这里我们要区分两个概念:图像处理和计算机视觉的区别:图像处理侧重于“处理”图像–如增强,还原,去噪,分割等等;而计算机视觉重点在于使用计算机来模拟人的视觉,因此模拟才是计算机视觉领域的最终目标。
OpenCV用C++语言编写,它具有C ++,Python,Java和MATLAB接口,并支持Windows,Linux,Android和Mac OS, 如今也提供对于C#、Ch、Ruby,GO的支持
OpenCV图像处理原理
一般的图像(模拟图像)不能直接用计算机来处理,必须先将图像转化为数字图像。把模拟图像分割成一个个像素,每个像素的亮度或灰度值用一个整数表示——图像的数字化
灰度:显示器是由像素矩阵组成,每个像素发光亮度按照灰阶(8bit下是 0-254)显示,灰阶越高亮度越高,图像中说明这个灰阶的值就是灰度。它是一个具体的数值,一般说法例如某某像素的灰度值是多少等。
灰度图像数字化 ,数字化其实就是化成同行同列的二维数组,而每个坐标存的就是相关的灰度值(0-255)(为什么是0-255?一个字节存放8bit,而图的储存一般都是以uint8类型存放,同时计算机时按照二进制存放数值,也就是2的8次方,也就是256)
1.图像的读取显示保存
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
Mat image; //创建一个空图像image
image = imread("/opt/MVS/bin/Temp/Data/new_image.bmp"); //读取文件夹中的图像
//检测图像是否加载成功
if (image.empty()) //检测image,无数据返回真
{
cout << "Could not open or find the image" << endl;
return -1;
}
namedWindow("IMAGE"); //创建显示窗口,不加这行代码,也能显示,默认窗口大小不能改变
imshow("IMAGE", image);
imwrite("/opt/MVS/bin/Temp/Data/new_image.bmp", image); //在指定路径保存图像
waitKey(0); //暂停,保持图像显示
return 0;
}
2.Mat创建图像,获取图像信息和感兴趣区域
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
Mat image1 = imread("/opt/MVS/bin/Temp/Data/new_image.bmp"); //读取图像;
if (image1.empty())
{
cout << "读取错误" << endl;
return -1;
}
imshow("image1", image1); //显示图像;
cout << "图像的行数: " << image1.rows << endl; //获取图像的高度;
cout << "图像的列数: " << image1.cols << endl; //获取图像的宽度;
cout << "图像的通道数: " << image1.channels() << endl; //获取图像的通道数,彩色图=3,灰度图=1;
cout << "图像的尺寸: " << image1.size << endl; //获取图像的尺寸,行*列;
Mat imageROI(image1, Rect(0,0,10,10)); //定义感兴趣区域
//其中Rect()有四个参数,Rect(a,b,c,d):
//a:感兴趣区域列(cols)的起点;
//b:感兴趣区域行(rows)的起点;
//c:感兴趣区域的列数(cols);
// d:感兴趣区域的行数(rows);
waitKey(0); //暂停,保持图像显示,等待按键结束
return 0;
}
机器视觉、图像处理中,从被处理的图像以方框、圆、椭圆、不规则多边形等方式勾勒出需要处理的区域,称为感兴趣区域,ROI。
在Halcon、OpenCV、Matlab等机器视觉软件上常用到各种算子(Operator)和函数来求得感兴趣区域ROI,并进行图像的下一步处理。 在图像处理领域,感兴趣区域(ROI) 是从图像中选择的一个图像区域,这个区域是你的图像分析所关注的重点。圈定该区域以便进行进一步处理。使用ROI圈定你想读的目标,可以减少处理时间,增加精度。
https://blog.csdn.net/AI_girl/article/details/114358685获取图像属性、感兴趣区域ROI及通道处理 https://blog.csdn.net/AI_girl/article/details/114358685
3.色彩空间转换
void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 );
(1).src(source):输入的源图像。为矩阵形式。
(2).dst(destination):输出的目标图像,即经过色彩转后我们需要得到的图像。也为矩阵形式。
(3).code:颜色空间转换的标识符,表示我们所要进行空间转换的结果。
(4).dstCn:目标图像中的通道数;如果参数为0,则从src和代码自动获得通道的数量。
所以以彩色图像为源图像进行颜色空间转换时,注意是“BGR2 ”
3.1灰度变换(灰度反转,对数变换,幂律(伽马)变换)
1.灰度反转
原理
灰度反转:将图像亮暗对调,可以增强图像中暗色区域细节
其中L为图像灰度级,0~255灰度图像的灰度级为256.
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
Mat image1, output_image, image1_gray; //定义输入图像,输出图像,灰度图像
image1 = imread(" in.jpg"); //读取图像;
if (image1.empty())
{
cout << "读取错误" << endl;
return -1;
}
cvtColor(image1, image1_gray, COLOR_BGR2GRAY); //灰度化
imshow(" image1_gray", image1_gray); //显示灰度图像
output_image = image1_gray.clone();
for (int i = 0; i < image1_gray.rows; i++)
{
for (int j = 0; j < image1_gray.cols; j++)
{
output_image.at<uchar>(i, j) = 255 - image1_gray.at<uchar>(i, j); //灰度反转
}
}
imshow("output_image", output_image); //显示反转图像
waitKey(0); //暂停,保持图像显示,等待按键结束
return 0;
}
convertTo的用法
convertTo函数一般用于CV_32s转为CV_8U:
void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;
参数
- m – 目标矩阵。如果m在运算前没有合适的尺寸或类型,将被重新分配。
- rtype – 目标矩阵的类型。因为目标矩阵的通道数与源矩阵一样,所以rtype也可以看做是目标矩阵的位深度。如果rtype为负值,目标矩阵和源矩阵将使用同样的类型。
- alpha – 尺度变换因子(可选)。默认值是1。即把原矩阵中的每一个元素都乘以alpha。
- beta – 附加到尺度变换后的值上的偏移量(可选)。默认值是0。即把原矩阵中的每一个元素都乘以alpha,再加上beta
4.直方图
要理解直方图,绕不开“亮度”这个概念。人们把亮度分为0到255共256个数值,数值越大,代表的亮度越高。其中0代表纯黑色的最暗区域,255表示最亮的纯白色,而中间的数字就是不同亮度的灰色。人们还进一步把这些亮度分为了5个区域,分别是黑色,阴影,中间调,高光和白色。
void calcHist( const Mat* images, int nimages,
const int* channels, InputArray mask,
OutputArray hist, int dims, const int* histSize,
const float** ranges, bool uniform=true, bool accumulate=false );
• images:输入的图像的指针;
• nimages:输入图像个数;
• channels:需要统计直方图的第几通道;
• mask:掩模,mask必须是一个8位(CV_8U)的数组并且和images的数组大小相同;
• hist:直方图计算的输出值;
• dims:输出直方图的维度(由channels指定);
• histSize:直方图中每个dims维度需要分成多少个区间(如果把直方图看作一个一个竖条的话,就是竖条的个数);
• ranges:统计像素值的区间;
• uniform=true:是否对得到的直方图数组进行归一化处理;
• accumulate=false:在多个图像时,是否累积计算像素值的个数;