【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().
注意:
【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