直方图的计算和绘制
反向投影
通道复制
模板匹配
模板匹配代码:
#include "pch.h"
#include <iostream>
#include<opencv2/opencv.hpp>
#include"opencv2/highgui/highgui.hpp"
#include"opencv2/imgproc/imgproc.hpp"
using namespace cv;
using namespace std;
#define WINDOW_NAME1 "【原始图像】" //为窗口标题定义的宏
#define WINDOW_NAME2 "【效果图像】" //为窗口标题定义的宏
Mat g_srcImage, g_templateImage, g_resultImage;
int g_nMatchMethod;
int g_nMaxTrackbarNum = 5;
void on_Matching(int, void*);
int main()
{
g_srcImage = imread("1.jpg", 1);
g_templateImage = imread("2.jpg", 1);
namedWindow(WINDOW_NAME1, CV_WINDOW_AUTOSIZE);
namedWindow(WINDOW_NAME2, CV_WINDOW_AUTOSIZE);
//创建滑动条并进行一次初始化
createTrackbar("方法", WINDOW_NAME1, &g_nMatchMethod, g_nMaxTrackbarNum, on_Matching);
on_Matching(0, 0);
waitKey(0);
return 0;
}
//回调函数
void on_Matching(int, void*)
{//给局部变量初始化
Mat srcImage;
g_srcImage.copyTo(srcImage);
//初始化用于结果输出的矩阵
int resultImage_cols = g_srcImage.cols - g_templateImage.cols + 1;
int resultImage_rows = g_srcImage.rows - g_templateImage.rows + 1;
g_resultImage.create(resultImage_cols, resultImage_rows, CV_32FC1);
//进行匹配和标准化
matchTemplate(g_srcImage, g_templateImage, g_resultImage, g_nMatchMethod);
normalize(g_resultImage, g_resultImage, 0, 1, NORM_MINMAX, -1, Mat());
//通过函数minMaxLoc 定位最匹配的位置
double minValue;
double maxValue;
Point minLocation;
Point maxLocation;
Point matchLocation;
minMaxLoc(g_resultImage, &minValue, &maxValue, &minLocation, &maxLocation, Mat());
//TM_SQDIFF和CV_TM_SQDIFF_NORMED,越小的数值有着更高的匹配结果,而其余的方法,数值越大匹配效果越好
if (g_nMatchMethod == TM_SQDIFF || g_nMatchMethod == CV_TM_SQDIFF_NORMED)
{
matchLocation = minLocation;
}
else
{
matchLocation = maxLocation;
}
//绘制出矩形,并显示最终结果
rectangle(srcImage, matchLocation, Point(matchLocation.x + g_templateImage.cols, matchLocation.y + g_templateImage.rows), Scalar(0, 0, 255), 2, 8, 0);
rectangle(g_resultImage, matchLocation, Point(matchLocation.x + g_templateImage.cols, matchLocation.y + g_templateImage.rows), Scalar(0, 0, 255), 2, 8, 0);
imshow(WINDOW_NAME1, srcImage);
imshow(WINDOW_NAME2, g_resultImage);
//除了相关匹配(TM CCORR)得到错误的匹配结果之外,其他5中匹配结果都较为准确
}
角点检测
角点检测可用于图像定位
确定图像强角点
代码:
#include "pch.h"
#include <iostream>
#include<opencv2/opencv.hpp>
#include"opencv2/highgui/highgui.hpp"
#include"opencv2/imgproc/imgproc.hpp"
using namespace cv;
using namespace std;
#define WINDOW_NAME "【Shi-Tomasi角点检测】" //为窗口标题定义的宏
#define WINDOW_NAME2 "【效果图像】" //为窗口标题定义的宏
Mat g_srcImage, g_grayImage;
int g_maxCornerNumber = 33;
int g_maxTrackbarNumber = 500;
RNG g_rng(12345);
void on_GoodFeaturesToTrack(int, void*)
{
//对于变量小于等于1的处理
if (g_maxCornerNumber <= 1)
{
g_maxCornerNumber = 1;
}
vector<Point2f> corners;
double qualityLevel = 0.01;//角点检测可接受的最小特征值
double minDistance = 10;//角点之间的最小距离
int blockSize = 3;//计算导数自相关矩阵时指定的邻域范围
double k = 0.04;//权重系数
Mat copy = g_srcImage.clone(); //复制源图像到一个临时变量中,作为感兴趣区域
goodFeaturesToTrack(g_grayImage,//输入图像
corners, //检测到的角点的输出向量
g_maxCornerNumber, //角点的最大数量
qualityLevel, //角点检测可接受的最小特征值
minDistance,//角点之间的最小距离
Mat(),//感兴趣区域
blockSize,//计算倒数自相关矩阵时指定的邻域范围
false,//不使用Harris角点检测
k);//权重系数
cout << ">此次检测到的角点数量为:" << corners.size() << endl;
//绘制检测到的角点
int r = 4;
for (unsigned int i = 0; i < corners.size(); i++)
{
//以随机的颜色绘制出角点
circle(copy, corners[i], r, Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)), -1, 8, 0);
}
imshow(WINDOW_NAME, copy);
}
int main()
{
g_srcImage = imread("10.jpg", 1);
cvtColor(g_srcImage, g_srcImage, COLOR_BGR2GRAY);
namedWindow(WINDOW_NAME, WINDOW_AUTOSIZE);
//创建窗口和滑动条,并进行显示和回调函数初始化
createTrackbar("最大角点数", WINDOW_NAME, &g_maxCornerNumber, g_maxTrackbarNumber, on_GoodFeaturesToTrack);
imshow(WINDOW_NAME, g_srcImage);
on_GoodFeaturesToTrack(0, 0);
waitKey(0);
return(0);
}
寻找亚像素角点