【1】inRange()函数
OpenCV中的inRange()函数可实现二值化功能(这点类似threshold()函数),更关键的是可以同时针对多通道进行操作,使用起来非常方便!主要是将在两个阈值内的像素值设置为白色(255),而不在阈值区间内的像素值设置为黑色(0),该功能类似于之间所讲的双阈值化操作。
函数原型(C++):
void inRange(InputArray src, InputArray lowerb,
InputArray upperb, OutputArray dst);
官方文档中的解释:Checks if array elements lie between the elements of two other arrays.即检查数组元素是否在另外两个数组元素值之间。这里的数组通常也就是矩阵Mat或向量。请注意:该函数输出的dst是一幅二值化之后的图像。
参数解释:
请注意:该函数输出的dst是一幅二值化之后的图像。
使用示例1:对于单通道数组:
即,如果一幅灰度图像的某个像素的灰度值在指定的高、低阈值范围之内,则在dst图像中令该像素值为255,否则令其为0,这样就生成了一幅二值化的输出图像。
使用示例1:对于双通道数组:
即,每个通道的像素值都必须在规定的阈值范围内!
三通道及多通道以此类推。
/*
功能:利用inRange()函数操作,实现阈值化
*/
#include
#include
#include
#include
using namespace std;
using namespace cv;
int main()
{
//------------【1】读取源图像并检查图像是否读取成功------------
Mat srcImage = imread("D:\\OutPutResult\\ImageTest\\deng.jpg");
if (!srcImage.data)
{
cout << "读取图片错误,请重新输入正确路径!\n";
system("pause");
return -1;
}
imshow("【源图像】", srcImage);
//------------【2】灰度转换------------
Mat srcGray;
cvtColor(srcImage, srcGray, CV_RGB2GRAY);
imshow("【灰度图】", srcGray);
//------------【3】利用inRange()函数对图像二值化------------
Mat dstImage;
inRange(srcGray, Scalar(75, 75, 75), Scalar(85, 85, 85), dstImage);
imshow("【利用inRange()函数实现阈值化】", dstImage);
waitKey(0);
return 0;
}
/*
功能:利用inRange()函数操作,找到黄色方块
*/
#include
#include
#include
#include
using namespace std;
using namespace cv;
int main()
{
//------------【1】读取源图像并检查图像是否读取成功------------
Mat srcImage = imread("1.jpg");
if (!srcImage.data)
{
cout << "读取图片错误,请重新输入正确路径!\n";
system("pause");
return -1;
}
Mat kernel;
//开操作处理
kernel = getStructuringElement(MORPH_RECT, Size(2, 2));
std::vector> contours;
std::vector hireachy;
Rect rect;
Point2f center;
float radius = 5;
Mat dstImage,dst;
inRange(srcImage, Scalar(0, 80, 80), Scalar(50, 255, 255), dstImage);
//开操作
morphologyEx(dstImage, dst, MORPH_OPEN, kernel);
//获取边界
findContours(dst, contours, hireachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));
//框选面积最大的边界
if (contours.size() > 0)
{
double maxArea = 0;
for (int i = 0; i < contours.size(); i++)
{
double area = contourArea(contours[static_cast(i)]);
if (area > maxArea)
{
maxArea = area;
rect = boundingRect(contours[static_cast(i)]);
minEnclosingCircle(contours[static_cast(i)], center, radius);
}
}
}
//矩形框
//rectangle(frame,rect, Scalar(0,255,0),2);
//圆形框
circle(srcImage, Point(center.x, center.y), (int)radius, Scalar(0, 255, 0), 2);
imshow("input", srcImage);
imshow("output", dst);
waitKey(0);
return 0;
}
上边界与下边界值,根据自己需要自行设置。
合理运用,可以结合其他内容实现对目前区域的提取与分割。
【2】cvtColor()函数
cv::cvtColor()用于将图像从一个颜色空间转换到另一个颜色空间的转换(目前常见的颜色空间均支持),并且在转换的过程中能够保证数据的类型不变,即转换后的图像的数据类型和位深与源图像一致。
具体调用形式如下:
void cv::cvtColor(
cv::InputArray src, // 输入序列
cv::OutputArray dst, // 输出序列
int code, // 颜色映射码
int dstCn = 0 // 输出的通道数 (0='automatic')
);
其中,最后一个参数dstCn用于指定目标图像的通道数,如果指定的值是默认值0,那么通道数将由输入图像和颜色转换码决定。
cv::cvtColor()支持多种颜色空间之间的转换,其支持的转换类型和转换码如下:
需要说明的是在opencv2.x时颜色空间转换code用的宏定义是CV_前缀开头,而在opencv3.x版本其颜色空间转换code宏定义更改为COLOR_开头
1、RGB和BGR(opencv默认的彩色图像的颜色空间是BGR)颜色空间的转换
cv::COLOR_BGR2RGB
cv::COLOR_RGB2BGR
cv::COLOR_RGBA2BGRA
cv::COLOR_BGRA2RGBA
2、向RGB和BGR图像中增添alpha通道
cv::COLOR_RGB2RGBA
cv::COLOR_BGR2BGRA
3、从RGB和BGR图像中去除alpha通道
cv::COLOR_RGBA2RGB
cv::COLOR_BGRA2BGR
4、从RBG和BGR颜色空间转换到灰度空间
cv::COLOR_RGB2GRAY
cv::COLOR_BGR2GRAY
cv::COLOR_RGBA2GRAY
cv::COLOR_BGRA2GRAY
5、从灰度空间转换到RGB和BGR颜色空间
cv::COLOR_GRAY2RGB
cv::COLOR_GRAY2BGR
cv::COLOR_GRAY2RGBA
cv::COLOR_GRAY2BGRA
6、RGB和BGR颜色空间与BGR565颜色空间之间的转换
cv::COLOR_RGB2BGR565
cv::COLOR_BGR2BGR565
cv::COLOR_BGR5652RGB
cv::COLOR_BGR5652BGR
cv::COLOR_RGBA2BGR565
cv::COLOR_BGRA2BGR565
cv::COLOR_BGR5652RGBA
cv::COLOR_BGR5652BGRA
7、灰度空间域BGR565之间的转换
cv::COLOR_GRAY2BGR555
cv::COLOR_BGR5552GRAY
8、RGB和BGR颜色空间与CIE XYZ之间的转换
cv::COLOR_RGB2XYZ
cv::COLOR_BGR2XYZ
cv::COLOR_XYZ2RGB
cv::COLOR_XYZ2BGR
9、RGB和BGR颜色空间与uma色度(YCrCb空间)之间的转换
cv::COLOR_RGB2YCrCb
cv::COLOR_BGR2YCrCb
cv::COLOR_YCrCb2RGB
cv::COLOR_YCrCb2BGR
10、RGB和BGR颜色空间与HSV颜色空间之间的相互转换
cv::COLOR_RGB2HSV
cv::COLOR_BGR2HSV
cv::COLOR_HSV2RGB
cv::COLOR_HSV2BGR
11、RGB和BGR颜色空间与HLS颜色空间之间的相互转换
cv::COLOR_RGB2HLS
cv::COLOR_BGR2HLS
cv::COLOR_HLS2RGB
cv::COLOR_HLS2BGR
12、RGB和BGR颜色空间与CIE Lab颜色空间之间的相互转换
cv::COLOR_RGB2Lab
cv::COLOR_BGR2Lab
cv::COLOR_Lab2RGB
cv::COLOR_Lab2BGR
13、RGB和BGR颜色空间与CIE Luv颜色空间之间的相互转换
cv::COLOR_RGB2Luv
cv::COLOR_BGR2Luv
cv::COLOR_Luv2RGB
cv::COLOR_Luv2BGR
14、Bayer格式(raw data)向RGB或BGR颜色空间的转换
cv::COLOR_BayerBG2RGB
cv::COLOR_BayerGB2RGB
cv::COLOR_BayerRG2RGB
cv::COLOR_BayerGR2RGB
cv::COLOR_BayerBG2BGR
cv::COLOR_BayerGB2BGR
cv::COLOR_BayerRG2BGR
cv::COLOR_BayerGR2BGR
需要特别说明的是RGB–>GRAY的转换是我们常用的转换格式,其转换公式如下:
上图中出现的RGBA格式图片,RGBA是代表Red(红色)、Green(绿色)、Blue(蓝色)和Alpha的色彩空间。虽然它有时候被描述为一个颜色空间,但是它其实是RGB模型附加了额外的信息,可以属于任何一种RGB颜色空间。Alpha参数一般用作不透明度参数,如果一个像素的alpha通道数值为0%,那它就是完全透明的也就是肉眼不可见,而数值为100%则意味着一个完全不透明的像素,传统的数字图像就是alpha值为100%。
需要注意的是cvtColor()函数不能直接将RGB图像转换为二值图像(Binary Image),需要借助threshold()函数,其具体用法请查阅threshold().
注意:
createTrackbar()函数用来创建一个可以调节输入变量值的滑动条,并将改控件依附于指定的窗口上。在使用时需要和一个回调函数配合使用。其原型如下:
CV_EXPORTS int createTrackbar(const string& trackbarname, const string& winname,
int* value, int count,
TrackbarCallback onChange = 0,
void* userdata = 0);
参数解释:
const string& trackname: 滑动条名字
. const string& winname: 想要把该滑动条依附到的窗口名字,在程序中可能该窗口名称由namedWindow()声明。
. int* value: 创建滑动条时,滑动条的初始值
. int count: 滑动条的最大值,即所有滑动条的数据变动都要在0-count之间,滑动条最小值为0
. TrackbarCallback onChange = 0: 这是指的回调函数,每次滑动条数据变化时都对该函数进行回调
. void* userdata = 0: 这个是用户传给回调函数的数据,用来处理滑动条数值变动。如果在创建滑动条时,输入value实参是全局变量,则本参数userdata可使用默认值0.
#include
#include
#include
#include
using namespace std;
using namespace cv;
//声明全局变量
const int g_nTrackbarMaxValue = 100; //滑动条最大值
int g_nTrackbarValue; //滑动条对应的值
double g_dAlphaValue; //第一幅图权重
double g_dBetaValue; //第二幅图权重
Mat g_srcImage1, g_srcImage2, g_distImage;
//声明回调函数
void on_Trackbar(int, void*);
int main()
{
g_srcImage1 = imread("forest.jpg");
g_srcImage2 = imread("rain.jpg");
//判断图像是否加载成功
if(g_srcImage1.data && g_srcImage2.data)
cout << "图像加载成功!" << endl << endl;
else
{
cout << "图像加载失败!" << endl << endl;
return -1;
}
namedWindow("混合后图像",WINDOW_NORMAL); //滑动条依附的窗口
g_nTrackbarValue = 20; //设置滑动条初始值
//在创建的窗体中创建滑动条控件并命名
char trackBarName[100];
/*Linux下使用sprintf需要添加头文件"stdio.h"
*在Windows下微软一直在推广其安全函数即后缀加上_s
*否则会有警告出现
*所以本段代码将有两个版本*/
sprintf(trackBarName, "透明度 %d", g_nTrackbarMaxValue); //Linux版本语句
//sprintf_s(trackBarName, "透明度 %d", g_nTrackbarMaxValue); //Windows版本语句
createTrackbar(trackBarName, "混合后图像", &g_nTrackbarValue, g_nTrackbarMaxValue, on_Trackbar);
on_Trackbar(g_nTrackbarValue, 0); //结果在回调函数中显示
waitKey(0);
return 0;
}
void on_Trackbar(int, void*)
{
//图像融合的权重在0-1之间,转换输入值和权重之间的比例
g_dAlphaValue = (double) g_nTrackbarValue / g_nTrackbarMaxValue;
g_dBetaValue = 1.0 - g_dAlphaValue; //第二幅图像权重
//使用addWeighted函数对图像进行线性混合
addWeighted(g_srcImage1, g_dAlphaValue, g_srcImage2, g_dBetaValue, 0.0, g_distImage);
imshow("混合后图像", g_distImage);
}
参考:https://blog.csdn.net/keith_bb/article/details/53174484
https://blog.csdn.net/sinat_36264666/article/details/78057256
https://blog.csdn.net/akadiao/article/details/78881026