如何手动注册图像(图像注册)
How to register an image manually (image registration)
我正在将代码从Matlab转换为C++,其中一个我不理解的函数是imtransform。我需要"配准"一个图像,这基本上意味着拉伸、倾斜和旋转我的图像,使其与另一个图像正确重叠。
Matlab的imtransform为您注册,但当我用C++编程时,我需要知道抽象了什么。图像配准中涉及的普通数学是什么?如何从2个数据阵列(组成图像)到1个阵列,即组合图像重叠?
我建议您在c++中使用OpenCV,并且有很多图像处理工具和函数可以调用和使用。
配准模块实现参数化图像配准。实现的方法是直接对齐,即直接使用像素值来计算一对图像之间的配准,而不是基于特征的配准。
表示这些模型的OpenCV常量具有前缀MOTION_
,并显示在括号内。
-
平移(
MOTION_TRANSLATION
):可以将第一个图像偏移(平移)(x,y)以获得第二个图像。我们只需要估计两个参数x和y。 -
欧几里得(
MOTION_EUCLIDEAN
):第一个图像是第二个图像的旋转和移位版本。有三个参数,x,y和角度。您将在图4中注意到,当一个正方形进行欧几里得变换时,其大小不变,平行线保持平行,变换后直角保持不变。 -
仿射(
MOTION_AFFINE
):仿射变换是旋转、平移(移位)、缩放和剪切的组合。此变换有六个参数。当正方形经过仿射变换时,平行线保持平行,但以直角相交的线不再保持正交。 -
同态(
MOTION_HOMOGRAPHY
):上面描述的所有变换都是2D变换。它们不考虑3D效果。另一方面,单应性变换可以解释一些3D效果(但不是全部)。此变换有8个参数。当使用单应性变换时,正方形可以变为任何四边形。
参考:https://docs.opencv.org/3.4.2/db/d61/group__reg.html
这是一个我发现对图像配准非常有用的例子:
#include <opencv2/opencv.hpp>
#include "opencv2/xfeatures2d.hpp"
#include "opencv2/features2d.hpp"
using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;
const int MAX_FEATURES = 500;
const float GOOD_MATCH_PERCENT = 0.15f;
void alignImages(Mat &im1, Mat &im2, Mat &im1Reg, Mat &h)
{
Mat im1Gray, im2Gray;
cvtColor(im1, im1Gray, CV_BGR2GRAY);
cvtColor(im2, im2Gray, CV_BGR2GRAY);
// Variables to store keypoints and descriptors
std::vector<KeyPoint> keypoints1, keypoints2;
Mat descriptors1, descriptors2;
// Detect ORB features and compute descriptors.
Ptr<Feature2D> orb = ORB::create(MAX_FEATURES);
orb->detectAndCompute(im1Gray, Mat(), keypoints1, descriptors1);
orb->detectAndCompute(im2Gray, Mat(), keypoints2, descriptors2);
// Match features.
std::vector<DMatch> matches;
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("BruteForce-Hamming");
matcher->match(descriptors1, descriptors2, matches, Mat());
// Sort matches by score
std::sort(matches.begin(), matches.end());
// Remove not so good matches
const int numGoodMatches = matches.size() * GOOD_MATCH_PERCENT;
matches.erase(matches.begin()+numGoodMatches, matches.end());
// Draw top matches
Mat imMatches;
drawMatches(im1, keypoints1, im2, keypoints2, matches, imMatches);
imwrite("matches.jpg", imMatches);
// Extract location of good matches
std::vector<Point2f> points1, points2;
for( size_t i = 0; i < matches.size(); i++ )
{
points1.push_back( keypoints1[ matches[i].queryIdx ].pt );
points2.push_back( keypoints2[ matches[i].trainIdx ].pt );
}
// Find homography
h = findHomography( points1, points2, RANSAC );
// Use homography to warp image
warpPerspective(im1, im1Reg, h, im2.size());
}
int main(int argc, char **argv)
{
// Read reference image
string refFilename("form.jpg");
cout << "Reading reference image : " << refFilename << endl;
Mat imReference = imread(refFilename);
// Read image to be aligned
string imFilename("scanned-form.jpg");
cout << "Reading image to align : " << imFilename << endl;
Mat im = imread(imFilename);
// Registered image will be resotred in imReg.
// The estimated homography will be stored in h.
Mat imReg, h;
// Align images
cout << "Aligning images ..." << endl;
alignImages(im, imReference, imReg, h);
// Write aligned image to disk.
string outFilename("aligned.jpg");
cout << "Saving aligned image : " << outFilename << endl;
imwrite(outFilename, imReg);
// Print estimated homography
cout << "Estimated homography : n" << h << endl;
}
Raw C++中没有任何您所提到的概念。但是,您可以使用许多C++的图像处理库来进行各种转换。DevIL和FreeImage应该能够进行分层,以及一些转换。
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 无法将结构注册为增强几何体3D点
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- OpenCV EqualizeHist()从彩色图像创建黑白图像
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 如何使用AngelScript注册SFML Vector2运算符
- 平均图像时图像损坏
- 在C++中使用GDAL可以将图像的像素坐标转换为lat,long吗
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- Vulkan验证层不断在VkQueuePresentKHR()上抛出图像布局错误
- 使用FFMPEG将RGB图像序列保存到.mp4时出现问题
- 将RGB图像保存为PPM格式
- 将图像添加到资源文件夹UWP C++
- 在遍历处理程序的向量时注册和注销处理程序
- 有没有任务栏API可以立即应用注册表更改
- 彩色图像的卤化物处理平均值
- 使用QJsEngine在Qt中注册自定义类型
- 张量流错误:执行器无法创建内核。没有注册'Snapshot' 适用于 GPU 设备的 OpKernel 运行图像标签示例
- 用c++将一个图像注册到一个图像堆栈
- 如何手动注册图像(图像注册)