OpenCV基础API函数一
OpenCV基础API函数二
OpenCV基础API函数三
OpenCV基础API函数四
VideoCapture 读取视频
VideoCapture是一个类 设置或获取VideoCapter属性 videoCapture.set()或者videoCapture.get()
例子:读取视频
void video()
{
//1 代表读取设备上的第二个摄像头 0代表第一个摄像头
VideoCapture videoCapture(1);
//读取视频文件
//VideoCapture videoCapture("F:\\Opencv\\opencv\\sources\\samples\\data\\vtest.avi");
//设置摄像头的像素 宽
videoCapture.set(CV_CAP_PROP_FRAME_WIDTH,8160);
//设置摄像头的像素 高
videoCapture.set(CAP_PROP_FRAME_HEIGHT,8160);
// 获取摄像头的像素 高
int h=videoCapture.get(CAP_PROP_FRAME_HEIGHT);
// 获取摄像头的像素 宽
int w=videoCapture.get(CAP_PROP_FRAME_WIDTH);
//获取视频的帧数
int fps = videoCapture.get(CAP_PROP_FPS);
//获取总帧数
int fps_count = videoCapture.get(CAP_PROP_FRAME_COUNT);
cout << "h " << h << " w " << w <<"fps "<<fps <<"fps_count"<<fps_count<< endl;
char c;
Mat src;
namedWindow("视频", WINDOW_FREERATIO);
while(true)
{
videoCapture.read(src);
if (src.empty())
{
break;
}
imshow("视频", src);
// 按'ESC'键退出
c=waitKey(10);
if(c==27)
{
break;
}
}
videoCapture.release();
}
HSV 颜色空间转换—抠图

inRange addWeighted相关API函数请看OpenCV基础API函数一
例子:抠图

void imageMatting()
{
//摄像头视频
VideoCapture videoCapture(1);
//文件视频
VideoCapture videoCaptureFile("C:\\Users\\Jason\\Desktop\\01.mp4");
if(!videoCapture.isOpened() || !videoCaptureFile.isOpened())
{
cout << "文件打开失败" << endl;
return;
}
videoCapture.set(CAP_PROP_FPS, videoCaptureFile.get(CAP_PROP_FPS));
namedWindow("frame", WINDOW_FREERATIO);
namedWindow("frameFile", WINDOW_FREERATIO);
namedWindow("mask", WINDOW_FREERATIO);
namedWindow("result", WINDOW_FREERATIO);
char c;
Mat frame, frameFile, hsv,mask;
Mat reault;
while (true)
{
videoCapture.read(frame);
videoCaptureFile.read(frameFile);
if (frame.empty() || frameFile.empty())
{
return;
}
//把摄像头文件视频大小转换到和文件视频大小一样
resize(frame, frame, Size(frameFile.cols, frameFile.rows));
reault = Mat::zeros(frameFile.size(), frameFile.type());
imshow("frame", frame);
imshow("frameFile",frameFile);
//转换到HSV色彩空间
cvtColor(frameFile, hsv, COLOR_BGR2HSV);
//获取HSV指定的色彩范围
inRange(hsv,Scalar(35,43,46),Scalar(77,255,255),mask);
mask = ~mask;
//把文件视频里指定的人物拷贝到result里面
imshow("mask", mask);
frameFile.copyTo(reault, mask);
//两幅图片相加
addWeighted(frame, 0.5, reault, 1, 0, reault);
imshow("result", reault);
c = waitKey(1);
if (c == 27)
{
break;
}
}
}
calcBackProject 直方图反射投影 寻找目标物体
void calcBackProject( const Mat* images, int nimages,
const int* channels, InputArray hist,
OutputArray backProject, const float** ranges,
double scale = 1, bool uniform = true );
返回值:空
images:输入的图片
ninages:图片的数量
hist:模板直方图
backProject:结果图像
ranges:每个维度直方图的取值范围
scale:是否缩放
uniform:是否归一化
例子:根据模板直方图,获取目标物体

void histReflect(Mat &src, Mat &srcModel)
{
Mat src_hsv, model_hsv, model_hist;
cvtColor(src, src_hsv, COLOR_BGR2HSV);
cvtColor(srcModel, model_hsv, COLOR_BGR2HSV);
int channles[] = {0, 1, 2};
int h_histSize = 16;
int s_histSize = 16;
int v_histSize = 16;
int histSize[] = {h_histSize, s_histSize, v_histSize};
float h_range[] = {0, 180};
float s_range[] = {0, 255};
float v_range[] = {0, 255};
const float *ranges[] = {h_range, s_range, v_range};
//获取直方图
calcHist(&model_hsv, 1, channles, Mat(), model_hist, 2, histSize, ranges);
//直方图归一化
normalize(model_hsv, model_hsv, 0, 255, NORM_MINMAX);
Mat backProject;
//直方图反射投影
calcBackProject(&src_hsv, 1, channles, model_hist, backProject, ranges);
imshow("直方图反射投影", backProject);
}
cornerHarris goodFeaturesToTrack 角点检测
void cornerHarris( InputArray src, OutputArray dst, int blockSize,
int ksize, double k,
int borderType = BORDER_DEFAULT );
返回值:空
src:输入的8bit灰度图像
dst:输出的角点检测的图像,类型是CV_32FC1 大小和src一样
blockSize:角点检测的邻域大小
ksize:sobel算子的窗口大小
k:Harris算法系数通常取 0.04---0.06
borderType :边缘填充方式
shi-tomasi角点检测算法性能高于Harris算法
void goodFeaturesToTrack( InputArray image, OutputArray corners,
int maxCorners, double qualityLevel, double minDistance,
InputArray mask = noArray(), int blockSize = 3,
bool useHarrisDetector = false, double k = 0.04 );
返回值:空
image:输入的8bit灰度图像
corners:角点的坐标 类型为vector<Point2f>
qualityLevel:角点的质量水平,大于这个值得角点被保留,小于这个值得角点舍弃
minDistance:两个角点的最小距离,小于这个值得角点舍弃
mask:图像掩码;计算图像的那个部分,若要计算全部 mask==Mat()
blockSize:角点检测的邻域大小
useHarrisDetector:是否使用Harris进行角点检测,
k:Harris角点算法的系数通常取 0.04---0.06
例子:发现角点

void harrisAngularPoint(Mat &src)
{
Mat gray;
cvtColor(src, gray, COLOR_BGR2GRAY);
Mat dst;
cornerHarris(gray, dst, 10, 3, 0.04);
normalize(dst, dst, 0, 255, NORM_MINMAX);
convertScaleAbs(dst, dst);
for (int row = 0; row < src.rows; ++row)
{
for(int col=0;col<src.cols;col++)
{
int value = dst.at<uchar>(row, col);
if(value>100)
{
circle(src, Point(col, row), 3, Scalar(255, 0, 0),-1);
}
}
}
namedWindow("结果", WINDOW_FREERATIO);
imshow("结果", src);
//shi-tomasi角点检测的效率要高于Harris角点检测
vector<Point2f> corners;
goodFeaturesToTrack(gray, corners, 500, 0.01, 3, Mat(), 3, false);
for (int row = 0; row < corners.size(); ++row)
{
circle(src, corners[row], 3, Scalar(255, 0, 0), -1);
}
namedWindow("结果2", WINDOW_FREERATIO);
imshow("结果2", src);
createBackgroundSubtractorMOG2 背景分析

//指针类型
//第一个参数 取多少帧进行计算背景
//第二个参数阈值
//第三个参数 是否分析阴影面积
Ptr<BackgroundSubtractorMOG2> bb = createBackgroundSubtractorMOG2(500, 32, false);
void myBackGroundExtract(Mat &src)
{
Mat mask, back,binary;
//应用此图像并获得Mask图像
bb->apply(src, mask, -1);
//获取背景
bb->getBackgroundImage(back);
namedWindow("mask",WINDOW_FREERATIO);
namedWindow("background",WINDOW_FREERATIO);
imshow("mask", mask);
imshow("background", back);
GaussianBlur(mask,mask,Size(0,0),3);
threshold(mask,binary,0,255,THRESH_BINARY|cv::THRESH_OTSU);
namedWindow("二值",WINDOW_FREERATIO);
imshow("二值", binary);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
// 发现轮廓
findContours(binary,contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE);
for (int i = 0; i < contours.size(); ++i)
{
double area= contourArea(contours[i],false);
if(area>100)
{
Rect box= boundingRect(contours[i]);
rectangle(src,box,Scalar(0,0,255),2);
}
}
namedWindow("src",WINDOW_FREERATIO);
imshow("src", src);
}
ORB 关键点检测
//创建ORB
auto orb = ORB::create();
static Ptr<ORB> create(int nfeatures=500, float scaleFactor=1.2f, int nlevels=8, int edgeThreshold=31,
int firstLevel=0, int WTA_K=2, int scoreType=ORB::HARRIS_SCORE, int patchSize=31, int fastThreshold=20);
返回值:指针类型的ORB
nfeatures:特征点的数量
scaleFactor:每层金字塔图像抽取比例 应大于1 当scaleFactor==2时表示经典的金字塔图像,即下一层的图像像素数比上一层像素数少四倍,,但太大的比因子会降低特征的匹配分数
nlevels;金字塔的层数
edgeThreshold:图像边界的阈值,不会被匹配
firstLevel:金字塔的第一层,需要放置原图
WTA_K:用于产生BIREF描述子的点对的个数,一般为2个,也可以设置为3个或4个,那么这时候描述子之间的距离计算就不能用汉明距离了,而是应该用一个变种。OpenCV中,如果设置WET_K = 2,则选用点对就只有2个点,匹配的时候距离参数选择NORM_HAMMING,如果WET_K设置为3或4,则BIREF描述子会选择3个或4个点,那么后面匹配的时候应该选择的距离参数为NORM_HAMMING2。
scoreType:用于对特征点进行排序的算法,你可以选择HARRIS_SCORE,也可以选择FAST_SCORE,但是它也只是比前者快一点点而已。
patchSize :用于计算BIREF描述子的特征点邻域大小。
virtual void detect( InputArray image,
CV_OUT std::vector<KeyPoint>& keypoints,
InputArray mask=noArray() );
返回值:空
image:原图像
keypoints:特征点集合
mask:指定在何处查找关键点的掩码 Mat()表示全局查找
例子: 角点检测

void myORB(Mat &src)
{
Mat dst;
//创建ORB处理类
auto orb=ORB::create(500);
//关键点集合
vector<KeyPoint> keyPoint;
//处理关键点
orb->detect(src,keyPoint);
//绘制关键点
drawKeypoints(src,keyPoint, dst,Scalar::all(-1));
for (int i = 0; i < keyPoint.size(); ++i)
{
circle(src,keyPoint.at(i).pt,3,Scalar(0,0,255),1);
}
namedWindow("ORB角点检测",WINDOW_FREERATIO);
imshow("ORB角点检测",src);
}
ORB 匹配
描述子
virtual void compute( InputArray image,
CV_OUT CV_IN_OUT std::vector<KeyPoint>& keypoints,
OutputArray descriptors );
image:原始图片
keypoints:关键点
descriptors:描述子 ORB的描述子是32位的2进制类型
创建匹配模式BFMatcher
static Ptr<BFMatcher> create( int normType=NORM_L2, bool crossCheck=false ) ;
返回值:指针类型 Ptr<BFMatcher>
normTyoe:匹配类型 NORM_L1, NORM_L2标准适合SIFT 和SURF;NORM_HAMMING标准适合ORB描述子,但是如果ORB的WTA_K=3或者WTA_K=4需要使用NORM_HAMMING2标准
crossCheck:交叉校验 当crossCheck=false 是标准模式
void match( InputArray queryDescriptors, InputArray trainDescriptors,
CV_OUT std::vector<DMatch>& matches, InputArray mask=noArray() ) const;
返回值:空
queryDescriptors:查询的描述子
trainDescriptors:模板描述子
matches:匹配结果容器
mask:匹配的范围
DMatch的结构
| DMatch的结构
| 意思 |
|---|
| queryIdx |
| trainIdx |
| imgIdx |
| distance |
例子:匹配两个图片的特征值

void Demo::ORBMatch(Mat& src_Template, Mat& src)
{
//创建ORB
Ptr<ORB> orb = ORB::create(500, 1.2f, 4);
//关键点容器
vector<KeyPoint> template_keyPoints;
vector<KeyPoint> src_keyPoints;
//获取关键点
orb->detect(src_Template, template_keyPoints, Mat());
orb->detect(src, src_keyPoints, Mat());
//描述子容器
Mat template_describe, src_describe;
//计算描述子
orb->compute(src_Template, template_keyPoints, template_describe);
orb->compute(src, src_keyPoints, src_describe);
//创建匹配模式
Ptr<BFMatcher> bf_matcher = BFMatcher::create(NORM_HAMMING,false);
//存储匹配结果
vector<DMatch> dmatcher;
//两个描述子进行匹配
bf_matcher->match(src_describe, template_describe ,dmatcher);
//过滤距离过大的描述子
int size = dmatcher.size();
for (vector<DMatch>::iterator itera = dmatcher.begin(); itera != dmatcher.end();)
{
if (itera->distance > 20)
{
itera=dmatcher.erase(itera);
}
itera++;
}
Mat dst;
//绘制
drawMatches(src_Template, template_keyPoints, src, src_keyPoints,dmatcher, dst);
namedWindow("匹配结果", WINDOW_FREERATIO);
imshow("匹配结果", dst);
}
warpPerspective 透视变换
Mat findHomography( InputArray srcPoints, InputArray dstPoints,
int method = 0, double ransacReprojThreshold = 3,
OutputArray mask=noArray(), const int maxIters = 2000,
const double confidence = 0.995);
返回值:透视变换矩阵
srcPoints:原图像的坐标点
dstpoints:目标坐标点
method:用于计算变换矩阵的方法 0 最小二值法 RANSAC基础鲁棒法 LMEDS - 最小中值鲁棒算法 RHO - PROSAC-基于PROSAC的鲁棒算法
ransacReprojThreshold:将点对视为内点的最大允许重投影错误阈值(仅用于RANSAC和RHO方法)。若srcPoints和dstPoints是以像素为单位的,则该参数通常设置在1到10的范围内。
mask:计算图像区域的掩码
maxlters:RANSAC算法的最大迭代次数,默认值为2000。
confidence:可信度值,取值范围为0到1.
void warpPerspective( InputArray src, OutputArray dst,
InputArray M, Size dsize,
int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT,
const Scalar& borderValue = Scalar());
返回值:空
src,原始图像
dst,目标图像
M:变换矩阵
Size:输出图像的大小
flags:插值器
borderMode :边界填充方式
borderValue:边界填充的颜色
例子: 透视变换 校正图片

void rectifyImage(Mat &src)
{
Mat binary,gray;
Mat dst;
if(src.channels()>1)
{
cvtColor(src, gray, COLOR_BGR2GRAY);
}
else
{
gray = src.clone();
}
//图像二值化
threshold(gray, binary, 0, 255, THRESH_BINARY_INV | cv::THRESH_OTSU);
imshow("二值化", binary);
//轮廓检测
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(binary, contours, hierarchy, RETR_LIST, CHAIN_APPROX_NONE, Point());
int index = 0;
double maxArea=0;
//发现最大轮廓
for (int i = 0; i < contours.size(); ++i)
{
double area = contourArea(contours[i], false);
if(area>maxArea)
{
index=i;
maxArea=area;
}
}
//轮廓拟合多边形
vector<Point2f> approxCurve;
approxPolyDP(contours[index], approxCurve,contours[index].size()*0.1 , true);
//对坐标点进行排序,确保不同图片的坐标点顺序的一致性
for (int i = 0; i < approxCurve.size(); ++i)
{
for (int j = 0; j < approxCurve.size(); ++j)
{
if(approxCurve[i].y<approxCurve[j].y)
{
Point2f pt=approxCurve[i];
approxCurve[i]=approxCurve[j];
approxCurve[j]=pt;
}
}
}
if(approxCurve[0].x>approxCurve[1].x)
{
Point2f pt=approxCurve[0];
approxCurve[0]=approxCurve[1];
approxCurve[1]=pt;
}
if(approxCurve[2].x>approxCurve[3].x)
{
Point2f pt=approxCurve[2];
approxCurve[2]=approxCurve[3];
approxCurve[3]=pt;
}
for (int i = 0; i < approxCurve.size(); ++i)
{
cout<<approxCurve[i]<<endl;
}
vector<Point2f> dst_keyPoint;
//输入目标点
dst_keyPoint.push_back(Point2f(0,0));
dst_keyPoint.push_back(Point2f(300,0));
dst_keyPoint.push_back(Point2f(0,500));
dst_keyPoint.push_back(Point2f(300,500));
cout<<"======================"<<endl;
for (int i = 0; i < dst_keyPoint.size(); ++i)
{
cout<<dst_keyPoint[i]<<endl;
}
//获取变换矩阵
Mat m= findHomography(approxCurve,dst_keyPoint,0);
//透视变换
warpPerspective(src,dst,m,Size(300,500));
imshow("结果", dst);
}
本文介绍了OpenCV的基础API应用,包括VideoCapture的视频读取,HSV颜色空间转换实现图像抠图,以及cornerHarris和goodFeaturesToTrack进行角点检测,ORB关键点检测与匹配。此外,还展示了透视变换、背景分析和图像校正等实用技术。
3608

被折叠的 条评论
为什么被折叠?



