OpenCV中的inRange()函数可实现二值化功能(这点类似threshold()函数),更关键的是可以同时针对多通道进行操作,使用起来非常方便!
函数原型(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:针对单通道图像
dst(I) = lowerb(I)0 ≤ src(I)0 < upperb(I)0
即,如果一幅灰度图像的某个像素的灰度值在指定的高、低阈值范围之内,则在dst图像中令该像素值为255,否则令其为0,这样就生成了一幅二值化的输出图像。
使用示例2:针对三通道图像
dst(I) = lowerb(I)0 ≤ src(I)0 < upperb(I)0 ∧ lowerb(I)1 ≤ src(I)1 < upperb(I)1 ∧lowerb(I)2 ≤ src(I)2 < upperb(I)2
即,每个通道的像素值都必须在规定的阈值范围内!
————————————————
版权声明:本文为CSDN博主「诗眼天涯」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xiaoyufei117122/article/details/53572904
//(基于颜色)对象检测与跟踪
#include <QCoreApplication>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
Rect roi;
void processFrame(Mat &mask,Rect &rect);
int main()
{
VideoCapture capture;
// capture.open("../image/1113.jpg")
capture.open(0);
if(!capture.isOpened())
{
printf("could not load video ...");
return;
}
Mat frame;
Mat Mask;
Mat kernel=getStructuringElement(MORPH_RECT,Size(3,3),Point(-1,-1));
while (capture.read(frame)) {
//
inRange(frame,Scalar(0,127,0),Scalar(122,255,120),mask);
imshow("mask",mask);
//轮廓发现位置标定
processFrame(mask,roi);
rectangle(frame,roi,Scalar(0,0,255),2,8,0);
imshow("frame",frame);
char c=waitKey(30);
if(c==27)
{
break;
}
}
capture.release();
return 0;
}
void processFrame(Mat &mask,Rect &rect)
{
vector<vector<Point>> contours;
vector<Vec4i> hireachy;
findContours(mask,contours,hireachy,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE,Point(0,0));
if(contours.size() >0)
{
double maxArea=0.0;
for(int i=0;i<contours.size();i++)
{
double area=contourArea(contours[i]);
if(area > maxArea)
{
maxArea=area;
rect=boundingRect(contours[i]);
}
}
}
else
{
rect={0,0,0,0};
}
}