基本概念
inRange() 函数是 OpenCV 中用于图像处理的一个非常有用的函数,即从图像中提取出介于指定范围内的像素值。这个函数在图像处理中特别有用,比如颜色检测、背景去除等应用。它主要用于图像的阈值处理,但与其他阈值方法(如 threshold())不同的是,inRange() 可以设定一个范围来过滤像素值,非常适合用于色彩空间的分割,如从视频或图像中分离出特定颜色的物体。该函数经常与 HSV 色彩空间结合使用,因为 HSV 色彩空间对颜色变化的反应更加直观和自然。
函数原型
在 OpenCV 中,inRange() 函数的原型如下:
void cv::inRange(InputArray src, InputArray lowerb,InputArray upperb, OutputArray dst)参数介绍:
src: 输入图像,通常是一个多通道数组(图像)。
lowerb: 数组元素的下界,包含与 src 相同数量的通道。
upperb: 数组元素的上界,同样包含与 src 相同数量的通道。
dst: 输出图像,与 src 尺寸和类型相同。对于 src 中的每个像素,如果其值在 lowerb 和 upperb 之间(包括这两个边界),则 dst 中的相应像素设置为 255(白色),否则设置为 0(黑色)。
使用示例
假设你想从一幅图像中分离出绿色的物体。一种常用的方法是将图像从 BGR 色彩空间转换到 HSV 色彩空间,然后使用 inRange() 函数根据 HSV 值范围来分割绿色。
步骤
1.读取图像:使用 cv::imread() 读取图像。
2.转换色彩空间:使用 cv::cvtColor() 将图像从 BGR 转换到 HSV。
3.定义颜色范围:在 HSV 色彩空间中定义绿色的上下界。
4.应用 inRange():使用 inRange() 函数分割出绿色区域。
5.显示结果:显示原始图像和分割后的图像。
示例代码1
#include "pch.h"#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
//int main()
{// 读取图像 Mat img = imread("98.png");if (img.empty()) {std::cout << "Could not read the image." << std::endl;return 1;}// 转换到 HSV Mat hsv;cvtColor(img, hsv, COLOR_BGR2HSV);// 定义绿色的 HSV 范围 // 注意:这些值可能需要根据实际图像进行调整 Scalar lower_green(25, 36, 25); // 较低的绿色 Scalar upper_green(255, 70, 255); // 较高的绿色 // 创建一个掩模 Mat mask;inRange(hsv, lower_green, upper_green, mask);// 使用掩模 Mat result;bitwise_and(img, img, result, mask);// 显示结果 namedWindow("Original Image", WINDOW_NORMAL);imshow("Original Image", img);namedWindow("Green Objects", WINDOW_NORMAL);imshow("Green Objects", result);waitKey(0);return 0;
}//注意:HSV 中的绿色范围(本例中的 lower_green 和 upper_green)可能需要根据你的特定应用场景进行调整。
//不同的光照条件和相机设置可能会影响图像中的 HSV 值。
运行结果1
红色分量
下面是一个使用 C++ 和 OpenCV 的 inRange() 函数的基本示例,以说明如何使用它来提取图像中的特定颜色:
1.导入必要的头文件:
#include <opencv2/opencv.hpp>
using namespace cv;2.加载图像:
Mat src = imread("path/to/your/image.jpg");
if (src.empty()) {std::cout << "Could not open or find the image" << std::endl;return -1;
}3.转换到HSV颜色空间:
在许多情况下,HSV 颜色模型比 RGB 更适合进行颜色分割,
因为颜色的属性(色调、饱和度、亮度)更清晰地分离了。
Mat hsv;
cvtColor(src, hsv, COLOR_BGR2HSV);4.定义阈值:
假设我们要选择特定的颜色范围,例如红色。我们需要定义两个向量来存储HSV颜色空间的下限和上限。
Scalar lower_red = {160, 100, 100}; // 这些值取决于你要选择的颜色
Scalar upper_red = {180, 255, 255};5.应用 inRange() 函数:
使用 inRange() 函数将图像像素与指定的阈值进行比较,并创建一个掩码,其中介于这两个阈值之间的像素值设置为白色(255),其余设置为黑色(0)。
Mat mask;
inRange(hsv, lower_red, upper_red, mask);6.显示结果:
显示原始图像和掩码图像以便对比查看效果。
namedWindow("Original Image", WINDOW_AUTOSIZE);
imshow("Original Image", src);namedWindow("Mask", WINDOW_AUTOSIZE);
imshow("Mask", mask);7.等待按键退出:
waitKey(0); // Wait for a keystroke in the window8.清理:
不要忘记释放所有使用的内存资源。
destroyAllWindows();以上步骤展示了如何使用 inRange() 函数来创建一个简单的颜色识别程序。
请注意,实际的颜色阈值可能需要根据具体的应用场景和光照条件进行调整。
完整代码2
#include "pch.h"//1.导入必要的头文件:
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;//2.加载图像:int main()
{Mat src = imread("58.jpeg");if (src.empty()){std::cout << "Could not open or find the image" << std::endl;return -1;}//3.转换到HSV颜色空间://在许多情况下,HSV 颜色模型比 RGB 更适合进行颜色分割,//因为颜色的属性(色调、饱和度、亮度)更清晰地分离了。Mat hsv;cvtColor(src, hsv, COLOR_BGR2HSV);//4.定义阈值://假设我们要选择特定的颜色范围,例如红色。我们需要定义两个向量来存储HSV颜色空间的下限和上限。Scalar lower_red = { 160, 100, 100 }; // 这些值取决于你要选择的颜色Scalar upper_red = { 180, 255, 255 };//5.应用 inRange() 函数://使用 inRange() 函数将图像像素与指定的阈值进行比较,并创建一个掩码,其中介于这两个阈值之间的像素值设置为白色(255),其余设置为黑色(0)。Mat mask;inRange(hsv, lower_red, upper_red, mask);//6.显示结果://显示原始图像和掩码图像以便对比查看效果。namedWindow("Original Image", WINDOW_NORMAL);imshow("Original Image", src);namedWindow("Mask", WINDOW_NORMAL);imshow("Mask", mask);//7.等待按键退出:waitKey(0); // Wait for a keystroke in the window//8.清理://不要忘记释放所有使用的内存资源。destroyAllWindows();return 0;//以上步骤展示了如何使用 inRange() 函数来创建一个简单的颜色识别程序。//请注意,实际的颜色阈值可能需要根据具体的应用场景和光照条件进行调整。
}
运行结果2
实验代码3
#include "pch.h"
//#pragma comment(lib, "opencv_world450d.lib")
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <opencv2/imgproc/types_c.h>
#include <iostream>
using namespace std;
using namespace cv;//输入图像
Mat img;
//灰度值归一化
Mat bgr;
//HSV图像
Mat hsv;
//色相
int hmin = 0;
int hmin_Max = 360;
int hmax = 180;
int hmax_Max = 180;
//饱和度
int smin = 0;
int smin_Max = 255;
int smax = 255;
int smax_Max = 255;
//亮度
int vmin = 106;
int vmin_Max = 255;
int vmax = 255;
int vmax_Max = 255;
//显示原图的窗口
string windowName = "src";
//输出图像的显示窗口
string dstName = "dst";
//输出图像
Mat dst;
//回调函数
void callBack(int, void*)
{//输出图像分配内存dst = Mat::zeros(img.size(), img.type());//掩码Mat mask;inRange(hsv, Scalar(hmin, smin, vmin), Scalar(hmax, smax, vmax), mask);//掩模到原图的转换for (int r = 0; r < bgr.rows; r++){for (int c = 0; c < bgr.cols; c++){if (mask.at<uchar>(r, c) == 255){dst.at<Vec3b>(r, c) = bgr.at<Vec3b>(r, c);}}}//输出图像imshow(dstName, dst);//保存图像//dst.convertTo(dst, CV_8UC3, 255.0, 0);imwrite("HSV_inRange.jpg", dst);
}
int main(int argc, char** argv)
{//输入图像img = imread("SBB.jpg");if (!img.data || img.channels() != 3)return -1;imshow(windowName, img);bgr = img.clone();//颜色空间转换cvtColor(bgr, hsv, CV_BGR2HSV);//cout << hsv << endl;//定义输出图像的显示窗口//namedWindow(dstName, WINDOW_GUI_EXPANDED);namedWindow(dstName, WINDOW_NORMAL);//调节色相 HcreateTrackbar("hmin", dstName, &hmin, hmin_Max, callBack);createTrackbar("hmax", dstName, &hmax, hmax_Max, callBack);//调节饱和度 ScreateTrackbar("smin", dstName, &smin, smin_Max, callBack);createTrackbar("smax", dstName, &smax, smax_Max, callBack);//调节亮度 VcreateTrackbar("vmin", dstName, &vmin, vmin_Max, callBack);createTrackbar("vmax", dstName, &vmax, vmax_Max, callBack);callBack(0, 0);waitKey(0);return 0;
}