#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <cmath>
#include <opencv2/opencv.hpp>
# define M_PI 3.14159265358979323846
using namespace std;
using namespace cv;
enum MyEnum
{
ONLY_LINES = 1,
LINES_AND_POINTS = 2,
COLOR_CODED_POINTS_X = 3,
COLOR_CODED_POINTS_Y = 4,
COLOR_CODED_POINTS_XpY = 5,
POINTS_DeepMatch = 6,
POINTS_DeepMatch_COLOR = 7
};
Mat draw_matches(Mat &matchingImage, vector<uchar> &inliersMask, MyEnum drawing_type, std::vector<Point2f> &obj, std::vector<Point2f> &scene, Mat &retained_matches, cv::Size &img1_size, cv::Size &img2_size)
{
if (drawing_type == ONLY_LINES)
{
for (size_t i = 0; i<inliersMask.size(); i++){
if (inliersMask[i])
{
line(matchingImage, obj[i], scene[i], Scalar(0, 0, 255));
}
}
}
else if (drawing_type == LINES_AND_POINTS)
{
for (size_t i = 0; i<inliersMask.size(); i++){
if (inliersMask[i])
{
line(matchingImage, obj[i], scene[i], Scalar(255, 0, 0));
circle(matchingImage, obj[i], 1, Scalar(0, 255, 255), 2);
circle(matchingImage, scene[i], 1, Scalar(0, 255, 0), 2);
}
}
}
else if ((drawing_type == COLOR_CODED_POINTS_X) || (drawing_type == COLOR_CODED_POINTS_Y) || (drawing_type == COLOR_CODED_POINTS_XpY))
{
Mat _1_255(256, 1, CV_8UC1, Scalar(0));
for (int i = 0; i < _1_255.rows; i++)
_1_255.at<uchar>(i, 0) = i;
Mat _colormap;
applyColorMap(_1_255, _colormap, COLORMAP_HSV);
int colormap_idx;
Scalar color;
for (size_t i = 0; i<inliersMask.size(); i++){
if (inliersMask[i])
{
if (drawing_type == COLOR_CODED_POINTS_X)
colormap_idx = int(obj[i].x * 256. / img1_size.width); //x - gradient
if (drawing_type == COLOR_CODED_POINTS_Y)
colormap_idx = int(obj[i].y * 256. / img1_size.height); //y - gradient
if (drawing_type == COLOR_CODED_POINTS_XpY)
colormap_idx = int((obj[i].x - img1_size.width * 0.5 + obj[i].y - img1_size.height * 0.5) * 256. / (img1_size.height * 0.5 + img1_size.width * 0.5)); //manhattan gradient
colormap_idx = colormap_idx >= 0 ? colormap_idx : 256 + colormap_idx;
const uchar* inData = _colormap.ptr<uchar>(colormap_idx);
color = Scalar(inData[0], inData[1], inData[2]);
circle(matchingImage, obj[i], 1, color, 2);
circle(matchingImage, scene[i], 1, color, 2);
}
}
}
else if (drawing_type == POINTS_DeepMatch)
{
int img1_p1_x, img1_p2_x, img1_p3_y, img1_p4_y;
int img2_p1_x, img2_p2_x, img2_p3_y, img2_p4_y;
int pixel = 6;
for (size_t i = 0; i<inliersMask.size(); i++){
if (inliersMask[i])
{
img1_p1_x = obj[i].x - pixel < 0 ? 0 : obj[i].x - pixel;
img1_p2_x = obj[i].x + pixel > img1_size.width - 1 ? img1_size.width - 1 : obj[i].x + pixel;
img1_p3_y = obj[i].y - pixel < 0 ? 0 : obj[i].y - pixel;
img1_p4_y = obj[i].y + pixel > img1_size.height - 1 ? img1_size.height - 1 : obj[i].y + pixel;
line(matchingImage, Point(img1_p1_x, obj[i].y), Point(img1_p2_x, obj[i].y), Scalar(255, 0, 0), 2);
line(matchingImage, Point(obj[i].x, img1_p3_y), Point(obj[i].x, img1_p4_y), Scalar(255, 0, 0), 2);
//右图点要进行减去左图宽度操作
img2_p1_x = scene[i].x - img1_size.width - pixel < 0 ? 0 : scene[i].x - pixel;
img2_p2_x = scene[i].x - img1_size.width + pixel > img2_size.width - 1 ? img2_size.width - 1 : scene[i].x + pixel;
img2_p3_y = scene[i].y - pixel < 0 ? 0 : scene[i].y - pixel;
img2_p4_y = scene[i].y + pixel > img2_size.height - 1 ? img2_size.height - 1 : scene[i].y + pixel;
line(matchingImage, Point(img2_p1_x, scene[i].y), Point(img2_p2_x, scene[i].y), Scalar(0, 0, 255), 2);
line(matchingImage, Point(scene[i].x, img2_p3_y), Point(scene[i].x, img2_p4_y), Scalar(0, 0, 255), 2);
}
}
}
else if (drawing_type == POINTS_DeepMatch_COLOR)
{
int img1_p1_x, img1_p2_x, img1_p3_y, img1_p4_y;
int img2_p1_x, img2_p2_x, img2_p3_y, img2_p4_y;
int pixel = 6;
//构建颜色矩阵
cv::Scalar tempVal = cv::mean(retained_matches);
float x1_mean = tempVal.val[0];
float y1_mean = tempVal.val[1];
Mat img1_xy;
vector<Mat> split_channel;
vector<Mat> merge_channel(2);
split(retained_matches, split_channel);
split_channel[0] -= x1_mean;
split_channel[1] -= y1_mean;
merge_channel[0] = split_channel[0];
merge_channel[1] = split_channel[1];
merge(merge_channel, img1_xy);
//Mat img1_xy_Transpose = img1_xy.t();
float aa = atan2(63.2115365, -211.2886977);
Mat img_score(img1_xy.size().height, 1, CV_32S, Scalar(0));
for (size_t k = 0; k < inliersMask.size(); k++){
double cos = double(img1_xy.at<int>(k, 0));
double sin = double(img1_xy.at<int>(k, 1));
int temp = int(128 * atan2(sin, cos) / M_PI);
//cpp像python一样求余 %
img_score.at<int>(k, 0) = temp - 256 * floor(temp / 256.00);
}
Mat _1_255(256, 1, CV_8UC1, Scalar(0));
for (int i = 0; i < _1_255.rows; i++)
_1_255.at<uchar>(i, 0) = i;
Mat _colormap;
applyColorMap(_1_255, _colormap, COLORMAP_HSV);
Scalar color;
for (size_t i = 0; i<inliersMask.size(); i++){
if (inliersMask[i])
{
const uchar* inData = _colormap.ptr<uchar>(img_score.at<int>(i, 0));
color = Scalar(inData[0], inData[1], inData[2]);
img1_p1_x = obj[i].x - pixel < 0 ? 0 : obj[i].x - pixel;
img1_p2_x = obj[i].x + pixel > img1_size.width - 1 ? img1_size.width - 1 : obj[i].x + pixel;
img1_p3_y = obj[i].y - pixel < 0 ? 0 : obj[i].y - pixel;
img1_p4_y = obj[i].y + pixel > img1_size.height - 1 ? img1_size.height - 1 : obj[i].y + pixel;
line(matchingImage, Point(img1_p1_x, obj[i].y), Point(img1_p2_x, obj[i].y), color, 2);
line(matchingImage, Point(obj[i].x, img1_p3_y), Point(obj[i].x, img1_p4_y), color, 2);
//右图点要进行减去左图宽度操作
img2_p1_x = scene[i].x - img1_size.width - pixel < 0 ? 0 : scene[i].x - pixel;
img2_p2_x = scene[i].x - img1_size.width + pixel > img2_size.width - 1 ? img2_size.width - 1 : scene[i].x + pixel;
img2_p3_y = scene[i].y - pixel < 0 ? 0 : scene[i].y - pixel;
img2_p4_y = scene[i].y + pixel > img2_size.height - 1 ? img2_size.height - 1 : scene[i].y + pixel;
line(matchingImage, Point(img2_p1_x, scene[i].y), Point(img2_p2_x, scene[i].y), color, 2);
line(matchingImage, Point(scene[i].x, img2_p3_y), Point(scene[i].x, img2_p4_y), color, 2);
}
}
}
return matchingImage;
}
//int main()
//{
// Mat imgLeft = imread("img1.ppm");
// Mat imgRight = imread("img3.ppm");
//
// int maxHeight = max(imgLeft.size().height, imgRight.size().height);
// Size sz = Size(imgLeft.size().width + imgRight.size().width, maxHeight);
// Mat matchingImage = Mat::zeros(sz, CV_8UC3);
// // 设置matchingImage的感兴趣区域大小并赋予原图
// Mat roi1 = Mat(matchingImage, Rect(0, 0, imgLeft.size().width, imgLeft.size().height));
// imgLeft.copyTo(roi1);
// Mat roi2 = Mat(matchingImage, Rect(imgLeft.size().width, 0, imgRight.size().width, imgRight.size().height));
// imgRight.copyTo(roi2);
//
// std::ifstream fout;
// fout.open("./opencv_coord_matchPoint.txt", std::fstream::out | std::fstream::in);
// if (!fout)
// {
// std::cerr << "error:========" << "File Not Opened" << std::endl;
// return -1;
// }
// //设置精度 小数点后两位
// //fout.setf(ios::fixed, ios::floatfield);
// //fout.precision(2);
// string sline;//每一行
// string out;
// string x1, y1, x2, y2;
// int i_x1, i_y1, i_x2, i_y2;
// std::vector<Point2f>obj;
// std::vector<Point2f>scene;
// while (getline(fout, sline))
// {
// istringstream sin(sline);
// sin >> x1 >> y1 >> x2 >> y2;
// //cout << x1 << " " << y1 << " " << x2 << " " << y2 << " " << "\n";
// i_x1 = std::stoi(x1);
// i_y1 = std::stoi(y1);
// i_x2 = std::stoi(x2);
// i_y2 = std::stoi(y2);
//
// obj.push_back(Point(i_x1 - 1, i_y1 - 1));
// scene.push_back(Point(imgLeft.size().width + i_x2 - 1, i_y2 - 1));
// }
//
// Mat retained_matches(obj.size(), 1, CV_32SC4, Scalar(0, 0, 0, 0));
// for (size_t p = 0; p < obj.size(); ++p)
// {
// retained_matches.at<Vec4i>(p, 0)[0] = obj[p].x;
// retained_matches.at<Vec4i>(p, 0)[1] = obj[p].y;
// retained_matches.at<Vec4i>(p, 0)[2] = scene[p].x - imgLeft.size().width;
// retained_matches.at<Vec4i>(p, 0)[3] = scene[p].y;
// }
//
//
// vector<uchar>inliersMask(obj.size());
// Mat H = findHomography(scene, obj, CV_FM_RANSAC, 1, inliersMask);
// MyEnum drawing_type = POINTS_DeepMatch_COLOR;
// Mat result = draw_matches(matchingImage, inliersMask, drawing_type, obj, scene, retained_matches, imgLeft.size(), imgRight.size());
// Mat showImg;
// resize(result, showImg, Size(matchingImage.cols / 2, matchingImage.rows / 2), 0, 0, INTER_LINEAR);
// imshow("draw_matchPoint", showImg);
// waitKey();
// return 0;
//}
int main()
{
Mat imgLeft = imread("img1.ppm");
Mat imgRight = imread("img2.ppm");
vector<KeyPoint> keyPoint1;
ORB orb(500000);
orb.detect(imgLeft, keyPoint1);
Mat descriImage1;
orb.compute(imgLeft, keyPoint1, descriImage1);
vector<KeyPoint> keyPoints2;
orb.detect(imgRight, keyPoints2);
Mat descriImage2;
orb.compute(imgRight, keyPoints2, descriImage2);
vector<DMatch> matches;
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("BruteForce-Hamming");
matcher->match(descriImage1, descriImage2, matches);
int maxHeight = max(imgLeft.size().height, imgRight.size().height);
Size sz = Size(imgLeft.size().width + imgRight.size().width, maxHeight);
Mat matchingImage = Mat::zeros(sz, CV_8UC3);
// 设置matchingImage的感兴趣区域大小并赋予原图
Mat roi1 = Mat(matchingImage, Rect(0, 0, imgLeft.size().width, imgLeft.size().height));
imgLeft.copyTo(roi1);
Mat roi2 = Mat(matchingImage, Rect(imgLeft.size().width, 0, imgRight.size().width, imgRight.size().height));
imgRight.copyTo(roi2);
double max_dist = 0; double min_dist = 100;
for (int i = 0; i < descriImage1.rows; i++)
{
double dist = matches[i].distance;
if (dist < min_dist) min_dist = dist;
if (dist > max_dist) max_dist = dist;
}
std::vector< DMatch > good_matches;
for (int i = 0; i < descriImage1.rows; i++)
{
if (matches[i].distance < 0.9*max_dist)
{
good_matches.push_back(matches[i]);
}
}
std::vector<Point2f>obj;
std::vector<Point2f>scene;
Mat retained_matches(good_matches.size(), 1, CV_32SC4, Scalar(0, 0, 0, 0));
int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
for (size_t i = 0; i < good_matches.size(); ++i)
{
x2 = keyPoints2[good_matches[i].trainIdx].pt.x + imgLeft.size().width;
y2 = keyPoints2[good_matches[i].trainIdx].pt.y;
obj.push_back(keyPoint1[good_matches[i].queryIdx].pt);
scene.push_back(cv::Point(x2, y2));
retained_matches.at<Vec4i>(i, 0)[0] = keyPoint1[good_matches[i].queryIdx].pt.x;
retained_matches.at<Vec4i>(i, 0)[1] = keyPoint1[good_matches[i].queryIdx].pt.y;
retained_matches.at<Vec4i>(i, 0)[2] = x2;
retained_matches.at<Vec4i>(i, 0)[3] = y2;
}
vector<uchar>inliersMask(obj.size());
Mat H = findHomography(scene, obj, CV_FM_RANSAC, 3, inliersMask);
MyEnum drawing_type = POINTS_DeepMatch_COLOR;
Mat result = draw_matches(matchingImage, inliersMask, drawing_type, obj, scene, retained_matches, imgLeft.size(), imgRight.size());
Mat showImg;
resize(result, showImg, Size(matchingImage.cols / 2, matchingImage.rows / 2), 0, 0, INTER_LINEAR);
imshow("draw_matchPoint", showImg);
waitKey();
return 0;
}
关于特征匹配可视化的cpp实现(参考多种示例)
最新推荐文章于 2023-07-01 23:22:28 发布