当前位置: 代码迷 >> 综合 >> inRange()函数、cvtColor()函数、createTrackbar()函数
  详细解决方案

inRange()函数、cvtColor()函数、createTrackbar()函数

热度:75   发布时间:2023-11-25 05:57:07.0

【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是一幅二值化之后的图像。

参数解释

  • 参数1:输入要处理的图像,可以为单通道或多通道。
  • 参数2:包含下边界的数组或标量。
  • 参数3:包含上边界数组或标量。
  • 参数4:输出图像,与输入图像src 尺寸相同且为CV_8U 类型。

请注意:该函数输出的dst是一幅二值化之后的图像。

 

使用示例1:对于单通道数组:
 

 

即,如果一幅灰度图像的某个像素的灰度值在指定的高、低阈值范围之内,则在dst图像中令该像素值为255,否则令其为0,这样就生成了一幅二值化的输出图像。

使用示例1:对于双通道数组:

即,每个通道的像素值都必须在规定的阈值范围内!

三通道及多通道以此类推。

 

/*功能:利用inRange()函数操作,实现阈值化
*/#include <opencv2/core/core.hpp>              
#include <opencv2/highgui/highgui.hpp>              
#include <opencv2/imgproc/imgproc.hpp>             
#include <iostream>            
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 <opencv2/core/core.hpp>              
#include <opencv2/highgui/highgui.hpp>              
#include <opencv2/imgproc/imgproc.hpp>             
#include <iostream>            
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<std::vector<Point>> contours;std::vector<Vec4i> 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<int>(i)]);if (area > maxArea){maxArea = area;rect = boundingRect(contours[static_cast<int>(i)]);minEnclosingCircle(contours[static_cast<int>(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().

    注意:

RGB转化到HSV的算法:(色调(H),饱和度(S),明度(V))
max=max (R ,G ,B );
min=min (R ,G ,B );
V=max (R ,G ,B );
S= (max-min )/max;
HSV颜色空间模型(圆锥模型)HSV颜色空间模型(圆锥模型)[2]
if (R = max ) H = (G-B )/ (max-min )* 60
if (G = max ) H = 120+ (B-R )/ (max-min )* 60
if (B = max ) H = 240 + (R-G )/ (max-min )* 60
if (H < 0 ) H = H+ 360
HSV转化到RGB的算法:
if (s = 0)
R=G=B=V;
else
H /= 60;
i = INTEGER(H);
f = H - i;
a = V * ( 1 - s );
b = V * ( 1 - s * f );
c = V * ( 1 - s * (1 - f ) );
switch(i)
case 0: R = V; G = c; B = a;
case 1: R = b; G = v; B = a;
case 2: R = a; G = v; B = c;
case 3: R = a; G = b; B = v;
case 4: R = c; G = a; B = v;
case 5: R = v; G = a; B = b;

【3】createTrackbar()函数

 

     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 <iostream>
#include <stdio.h>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>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