首先是关于怎么产生txt文件,六位数
格式如下:
总数
x y x y Score 未知
x y x y Score 未知
写入代码:
方式:匹配距离为分数
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
using namespace std;
using namespace cv;
#include <direct.h>
#include <iomanip>
#include <fstream>
int main()
{
Ptr<Feature2D> f2d = xfeatures2d::SIFT::create(200);
Mat img_1 = imread("img1.ppm");
Mat img_2 = imread("img2.ppm");
resize(img_1, img_1,Size(480,640));
resize(img_2, img_2, Size(480, 640));
imwrite("img1.jpg", img_1);
imwrite("img2.jpg", img_2);
vector<KeyPoint> keypoints_1, keypoints_2;
f2d->detect(img_1, keypoints_1);
f2d->detect(img_2, keypoints_2);
Mat descriptors_1, descriptors_2;
f2d->compute(img_1, keypoints_1, descriptors_1);
f2d->compute(img_2, keypoints_2, descriptors_2);
BFMatcher matcher;
vector<DMatch> matches;
matcher.match(descriptors_1, descriptors_2, matches);
//------------------------------------------------------
vector<cv::Point2f> queryCoord;
vector<cv::Point2f> objectCoord;
for (int i = 0; i < matches.size(); i++){
queryCoord.push_back((keypoints_1[matches[i].queryIdx]).pt);
objectCoord.push_back((keypoints_2[matches[i].trainIdx]).pt);
}
Mat H_mask;
Mat H = findHomography(queryCoord, objectCoord, CV_RANSAC, 10, H_mask);
vector<DMatch> RANSAC_matches;
vector<KeyPoint> RANSAC_keypoint01, RANSAC_keypoint02;
vector<cv::Point2f> queryInliers;
vector<cv::Point2f> sceneInliers;
for (int i = 0; i < H_mask.rows; i++){
if (H_mask.at<uchar>(i) == 1){
queryInliers.push_back(queryCoord[i]);
sceneInliers.push_back(objectCoord[i]);
RANSAC_matches.push_back(matches[i]);
RANSAC_keypoint01.push_back(keypoints_1[matches[i].queryIdx]);
RANSAC_keypoint02.push_back(keypoints_2[matches[i].trainIdx]);
//RANSAC_matches[i].queryIdx = i;
//RANSAC_matches[i].trainIdx = i;
}
else {
}
}
//------------------------------------------------------
//######################################################
// 使用python显示匹配对(位置取整)和打分(颜色,分数可由匹配点的健壮性(左点,右点,左右点平均)表示,也可以由匹配对的距离)
// 例如516 148 510 346 4.29191 1497
/*
//float 位置为原本数值,保留两位小数
std::ofstream fout;
// ios::app 以追加的方式打开文件 ,ios::in 文件以输入方式打开 ios::out 文件以输出方式打开
fout.open("./SiftMatchingImage.txt", std::fstream::in | std::fstream::out | std::fstream::app);
if (!fout)
{
std::cerr << "error:========" << "File Not Opened" << std::endl;
return -1;
}
fout.setf(ios::fixed, ios::floatfield); // 设定为 fixed 模式,以小数点表示浮点数
fout.precision(2); // 设置精度 小数点后两位
fout << RANSAC_matches.size() << std::endl; // 输入匹配数 回车 方便python进行for循环
for (size_t i = 0; i < RANSAC_matches.size(); i++)
{
Point2f Lpt = keypoints_1[RANSAC_matches[i].queryIdx].pt;
Point2f Rpt = keypoints_2[RANSAC_matches[i].trainIdx].pt;
fout << Lpt.x << ' ' << Lpt.y << ' ' << Rpt.x << ' ' << Rpt.y << ' ' << RANSAC_matches[i].distance << ' ' << 1 << std::endl;
// 每行六个数 第五个是分值作用形成热力图 最后一个作用未知
if (i == RANSAC_matches.size() - 1)
fout << Lpt.x << ' ' << Lpt.y << ' ' << Rpt.x << ' ' << Rpt.y << ' ' << RANSAC_matches[i].distance << ' ' << 1;
}
fout.close();
*/
// int 位置为整型
std::ofstream fout;
// ios::app 以追加的方式打开文件 ,ios::in 文件以输入方式打开 ios::out 文件以输出方式打开
// 追加模式就是打开后,不清空,接着弄
//fout.open("./SiftMatchingImage.txt", std::fstream::in | std::fstream::out | std::fstream::app);
fout.open("./SiftMatchingImage.txt", std::fstream::in | std::fstream::out | std::fstream::trunc);
if (!fout)
{
std::cerr << "error:========" << "File Not Opened" << std::endl;
return -1;
}
fout << RANSAC_matches.size() << ' ' << 0 << ' ' << 0 << ' ' << 0 << ' ' << 0 << ' ' << 0 << std::endl; // 输入匹配数 回车 方便python进行for循环
for (size_t i = 0; i < RANSAC_matches.size(); i++)
{
Point2f Lpt = keypoints_1[RANSAC_matches[i].queryIdx].pt;
Point2f Rpt = keypoints_2[RANSAC_matches[i].trainIdx].pt;
// 每行六个数 第五个是分值作用形成热力图 最后一个作用未知
if (i == RANSAC_matches.size() - 1)
fout << int(Lpt.x) << ' ' << int(Lpt.y) << ' ' << int(Rpt.x) << ' ' << int(Rpt.y) << ' ' << RANSAC_matches[i].distance << ' ' << 100;
else
fout << int(Lpt.x) << ' ' << int(Lpt.y) << ' ' << int(Rpt.x) << ' ' << int(Rpt.y) << ' ' << RANSAC_matches[i].distance << ' ' << 100 << std::endl;
}
fout.close();
//######################################################
Mat img_matches;
drawMatches(img_1, keypoints_1, img_2, keypoints_2, RANSAC_matches,
img_matches, Scalar(0, 255, 0), Scalar::all(-1),
vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
imshow("match", img_matches);
waitKey();
return 0;
}
输入如下:
103 0 0 0 0 0
224 284 212 327 227.297 100
445 182 351 165 71.9166 100
444 179 351 164 136.77 100
444 178 351 164 183.638 100
443 288 368 253 86.6545 100
194 395 209 439 96.5505 100
328 321 295 321 190.455 100
304 484 306 470 241.609 100
372 366 333 343 120.487 100
272 336 257 355 118.886 100
304 507 311 491 142.944 100
272 336 257 355 131.708 100
326 194 271 213 183.469 100
307 187 257 213 172.725 100
307 187 257 213 140.371 100
167 379 185 436 134.458 100
257 510 277 514 212.57 100
191 322 194 376 162.444 100
172 377 188 432 193.484 100
315 190 263 213 176.771 100
76 511 137 599 231.985 100
14 468 76 589 290.587 100
324 506 325 481 204.034 100
318 187 265 210 155.258 100
15 391 64 515 219.47 100
271 341 257 360 168.79 100
74 347 105 447 168.205 100
260 505 278 508 196.079 100
17 441 74 562 296.847 100
270 487 282 489 257.54 100
58 289 80 401 163.018 100
61 281 81 392 216.171 100
58 167 58 287 90.111 100
58 167 58 287 130.599 100
230 593 274 598 119.892 100
268 482 285 483 372.61 100
231 362 231 394 224.711 100
231 362 231 394 137.332 100
69 289 90 396 226.201 100
179 314 183 372 157.156 100
67 270 84 380 135.857 100
221 355 223 392 187.585 100
65 516 129 609 164.058 100
183 243 172 307 131.13 100
348 67 265 98 140.648 100
64 299 87 407 203.106 100
23 458 82 576 210.53 100
183 243 172 307 116.465 100
219 369 224 406 123.746 100
183 409 203 457 170.129 100
24 379 69 500 221.267 100
266 478 285 479 378.556 100
266 478 285 479 399.001 100
180 250 172 315 142.503 100
180 250 172 315 105.128 100
264 500 280 503 137.888 100
264 486 278 490 174.057 100
181 318 185 376 166.736 100
456 327 383 280 179.53 100
286 345 269 357 149.282 100
240 360 238 389 204.078 100
215 374 221 412 143.558 100
286 345 269 357 179.491 100
215 526 252 547 133.933 100
144 512 192 566 289.467 100
146 565 205 614 193.08 100
143 370 164 439 152.729 100
243 482 262 495 173.194 100
243 482 262 495 152.039 100
244 487 263 500 195.893 100
148 300 156 373 131.092 100
137 499 185 558 259.21 100
244 487 263 500 157.191 100
137 558 195 611 161.527 100
137 499 185 558 272.485 100
150 198 139 280 103.247 100
246 478 263 491 201.465 100
154 541 206 588 196.525 100
207 355 211 397 159.06 100
339 248 290 255 181.48 100
36 505 103 613 86.7986 100
36 505 103 613 125.431 100
207 355 211 397 140.823 100
127 533 183 593 220.036 100
251 368 247 392 233.752 100
126 177 116 270 221.217 100
126 177 116 270 146.598 100
200 192 177 256 206.572 100
125 546 185 607 215.792 100
276 479 285 479 177.505 100
296 244 259 267 138.398 100
276 479 285 479 146.857 100
197 512 232 542 201.296 100
160 184 144 263 209.695 100
332 362 303 356 192.481 100
115 462 159 535 229.34 100
115 462 159 535 261.459 100
162 582 221 622 148.563 100
162 532 211 576 223.37 100
274 487 285 486 201.554 100
164 540 214 582 318.173 100
194 395 209 439 98.4683 100
190 248 180 309 132.223 100
190 248 180 309 132.223 100
python3需要安装库
matplotlib
numpy
PIL (3里面改名为Pillow)
安装方式:
pip install matplotlib
pip install numpy
pip install Pillow
import sys
from PIL import Image
from numpy import *
import numpy as np
from matplotlib.pyplot import *
# Python数组下标从0开始
def show_correspondences(img0, img1, corr):
assert corr.shape[-1] == 6
corr = corr[corr[:, 4] > 0, :]
# make beautiful colors
center = corr[:, [1, 0]].mean(axis=0) # array(img0.shape[:2])/2 #
corr[:, 5] = arctan2(*(corr[:, [1, 0]] - center).T)
corr[:, 5] = int32(64 * corr[:, 5] / pi) % 128 # 对分数进行计算
set_max = set(corr[:, 5])
colors = {m: i for i, m in enumerate(set_max)}
colors = {m: cm.hsv(i / float(len(colors))) for m, i in colors.items()}
def motion_notify_callback(event):
if event.inaxes == None: return
numaxis = event.inaxes.numaxis
if numaxis < 0: return
x, y = event.xdata, event.ydata
ax1.lines = []
ax2.lines = []
n = sum((corr[:, 2 * numaxis:2 * (numaxis + 1)] - [x, y]) ** 2, 1).argmin() # find nearest point
print("\rdisplaying #%d (%d,%d) --> (%d,%d), score=%g from maxima %d" % (n,
corr[n, 0], corr[n, 1], corr[n, 2],
corr[n, 3], corr[n, 4], corr[n, 5]), );
sys.stdout.flush()
x, y = corr[n, 0:2]
ax1.plot(x, y, '+', ms=10, mew=2, color='blue', scalex=False, scaley=False)
x, y = corr[n, 2:4]
ax2.plot(x, y, '+', ms=10, mew=2, color='red', scalex=False, scaley=False)
# we redraw only the concerned axes
renderer = fig.canvas.get_renderer()
ax1.draw(renderer)
ax2.draw(renderer)
fig.canvas.blit(ax1.bbox)
fig.canvas.blit(ax2.bbox)
def noticks():
xticks([])
yticks([])
clf()
ax1 = subplot(221)
ax1.numaxis = 0
imshow(img0, interpolation='nearest')
noticks()
ax2 = subplot(222)
ax2.numaxis = 1
imshow(img1, interpolation='nearest')
noticks()
ax = subplot(223)
ax.numaxis = -1
img3 = (img0 // 2) + 64 # 这里python3和python2的区别就是 python3 整除需要 // 斜杠
imshow(img3, interpolation='nearest')
imshow(img0 // 2 + 64, interpolation='nearest')
for m in set_max:
plot(corr[corr[:, 5] == m, 0], corr[corr[:, 5] == m, 1], '+', ms=10, mew=2, color=colors[m], scalex=0, scaley=0)
noticks()
ax = subplot(224)
ax.numaxis = -1
imshow(img1 // 2 + 64, interpolation='nearest')
for m in set_max:
plot(corr[corr[:, 5] == m, 2], corr[corr[:, 5] == m, 3], '+', ms=10, mew=2, color=colors[m], scalex=0, scaley=0)
noticks()
subplots_adjust(left=0.01, bottom=0.01, right=0.99, top=0.99,
wspace=0.02, hspace=0.02)
fig = get_current_fig_manager().canvas.figure
cid_move = fig.canvas.mpl_connect('motion_notify_event', motion_notify_callback)
print("Move your mouse over the top images to visualize individual matches")
show()
fig.canvas.mpl_disconnect(cid_move)
if __name__ == '__main__':
img= Image.open('img1.jpg')
img0 = array(img.convert('RGB'))
img = Image.open('img2.jpg')
img1 = array(img.convert('RGB'))
a = np.loadtxt("SiftMatchingImage.txt")
print(a.shape)
print(a[0][0])
cycle = int(a[0][0]) #取整
# args = sys.argv[1:]
retained_matches = []
for i in range(2,cycle+1):
x0 = a[i][0]
y0 = a[i][1]
x1 = a[i][2]
y1 = a[i][3]
score = a[i][4]
index = a[i][5]
retained_matches.append((float(x0), float(y0), float(x1), float(y1), float(score), float(index)))
'''
for line in sys.stdin:
line = line.split()
if not line or len(line) != 6 or not line[0][0].isdigit():
continue
x0, y0, x1, y1, score, index = line
retained_matches.append((float(x0), float(y0), float(x1), float(y1), float(score), float(index)))
'''
assert retained_matches, 'error: no matches piped to this program'
show_correspondences(img0, img1, array(retained_matches))
效果图:
输出信息:
或者
float core1 = keypoints_1[RANSAC_matches[i].queryIdx].response;
float core2 = (keypoints_1[RANSAC_matches[i].queryIdx].response
+ keypoints_2[RANSAC_matches[i].queryIdx].response) / 2;
if (i == RANSAC_matches.size() - 1)
fout << int(Lpt.x) << ' ' << int(Lpt.y) << ' ' << int(Rpt.x) << ' ' << int(Rpt.y) << ' ' << core1 << ' ' << 100;
else
fout << int(Lpt.x) << ' ' << int(Lpt.y) << ' ' << int(Rpt.x) << ' ' << int(Rpt.y) << ' ' << core1 << ' ' << 100 << std::endl;
103 0 0 0 0 0
224 284 212 327 0.0674072 100
445 182 351 165 0.0650815 100
444 179 351 164 0.0619935 100
444 178 351 164 0.0628061 100
443 288 368 253 0.0718054 100
194 395 209 439 0.0720539 100
328 321 295 321 0.0629363 100
304 484 306 470 0.0729251 100
372 366 333 343 0.0619105 100
272 336 257 355 0.062991 100
304 507 311 491 0.0729527 100
272 336 257 355 0.062991 100
326 194 271 213 0.0685247 100
307 187 257 213 0.0747844 100
307 187 257 213 0.0747844 100
167 379 185 436 0.0634785 100
257 510 277 514 0.0801529 100
191 322 194 376 0.0715812 100
172 377 188 432 0.0629583 100
315 190 263 213 0.0639087 100
76 511 137 599 0.0639834 100
14 468 76 589 0.0665046 100
324 506 325 481 0.067259 100
318 187 265 210 0.0696045 100
15 391 64 515 0.0639838 100
271 341 257 360 0.0795075 100
74 347 105 447 0.0675084 100
260 505 278 508 0.0737417 100
17 441 74 562 0.0717229 100
270 487 282 489 0.073429 100
58 289 80 401 0.0652272 100
61 281 81 392 0.0662907 100
58 167 58 287 0.074753 100
58 167 58 287 0.074753 100
230 593 274 598 0.0670991 100
268 482 285 483 0.088315 100
231 362 231 394 0.0694782 100
231 362 231 394 0.0694782 100
69 289 90 396 0.0666571 100
179 314 183 372 0.0647393 100
67 270 84 380 0.0666642 100
221 355 223 392 0.0620201 100
65 516 129 609 0.0705707 100
183 243 172 307 0.0754092 100
348 67 265 98 0.0708198 100
64 299 87 407 0.0726368 100
23 458 82 576 0.063851 100
183 243 172 307 0.0754092 100
219 369 224 406 0.0636333 100
183 409 203 457 0.0637613 100
24 379 69 500 0.0666485 100
266 478 285 479 0.0685912 100
266 478 285 479 0.0685912 100
180 250 172 315 0.0838269 100
180 250 172 315 0.0838269 100
264 500 280 503 0.0810512 100
264 486 278 490 0.0862029 100
181 318 185 376 0.0701052 100
456 327 383 280 0.0694957 100
286 345 269 357 0.0690673 100
240 360 238 389 0.0675513 100
215 374 221 412 0.0837878 100
286 345 269 357 0.0690673 100
215 526 252 547 0.0775359 100
144 512 192 566 0.0630356 100
146 565 205 614 0.0680354 100
143 370 164 439 0.0673343 100
243 482 262 495 0.0713394 100
243 482 262 495 0.0713394 100
244 487 263 500 0.0714509 100
148 300 156 373 0.063367 100
137 499 185 558 0.068794 100
244 487 263 500 0.0714509 100
137 558 195 611 0.0694037 100
137 499 185 558 0.0686522 100
150 198 139 280 0.0770634 100
246 478 263 491 0.0672728 100
154 541 206 588 0.0675175 100
207 355 211 397 0.0628953 100
339 248 290 255 0.0681105 100
36 505 103 613 0.0782181 100
36 505 103 613 0.0782181 100
207 355 211 397 0.0636687 100
127 533 183 593 0.0624714 100
251 368 247 392 0.0851211 100
126 177 116 270 0.0871578 100
126 177 116 270 0.0871578 100
200 192 177 256 0.0634787 100
125 546 185 607 0.065204 100
276 479 285 479 0.0701223 100
296 244 259 267 0.0683423 100
276 479 285 479 0.0701223 100
197 512 232 542 0.0716951 100
160 184 144 263 0.0701081 100
332 362 303 356 0.0729785 100
115 462 159 535 0.0771681 100
115 462 159 535 0.0771681 100
162 582 221 622 0.07827 100
162 532 211 576 0.0708267 100
274 487 285 486 0.0658922 100
164 540 214 582 0.065799 100
194 395 209 439 0.0720539 100
190 248 180 309 0.061159 100
对比一下:
长的差不多。。。。。
之所以没显示,是因为下面这段代码
源程序是python2的,img1 / 2 + 64是希望图像变暗变灰一点,方便显示彩色星状图标
其意思是将图像矩阵所有值,img1 / 2 + 64
但是在python3中不行,应该是语法的更改
ax = subplot(224)
ax.numaxis = -1
imshow(img1 / 2 + 64, interpolation='nearest')
for m in set_max:
plot(corr[corr[:, 5] == m, 2], corr[corr[:, 5] == m, 3], '+', ms=10, mew=2,
color=colors[m], scalex=0, scaley=0)
noticks()
改正: