我有一个像国际象棋这样的棋盘游戏。我有两张从鸟的角度拍摄的照片,例如:
图像的每个角都有一个标记1,它可以帮助我扭曲两张照片,这样即使它们可能是从稍微不同的角度拍摄的,但它们之后看起来几乎相同。
其中一张图像的某个位置上有所有棋盘游戏人物,而另一张图像/图片则没有。
现在,在我使用标记作为新图像中的新角并扭曲两张图片后,我只想得到棋盘游戏人物(所以基本上在扭曲之后,我想要两张图片的差异) 。
我现在的问题是,简单的 mat1-mat2
或 cv::substract
不起作用,因为它是精确的,并且如果这些图片的扭曲不是100% 完美的结果根本没有帮助。
我想构建一个数组,其中包含棋盘游戏人物的位置,这意味着如果我的想法可行,我可能会更容易找到人物。 实现这一目标的正确方法是什么?在这种情况下,背景扣除是否是正确的做法?
(请注意,我不想用标记交换我的棋盘游戏人物。角落上的标记对我来说已经是一种妥协。
1我期待使用 Aruco 来实现此目的,如果您建议替代方案,我不妨尝试一下。
最佳答案
您应该看看Image Registration .
我从 OpenCV samples 改编了以下代码
给定两个不同的棋盘图像(这里我给你拍摄了原始图像并稍微扭曲了一点)
您可以注册它们,获取结果图像:
两者之间存在差异:
您可以看到棋盘对齐得很好。注册已经照顾到了不同的观点。
代码:
#include <opencv2\opencv.hpp>
#include <opencv2\reg\mappergradproj.hpp>
#include <opencv2\reg\mapperpyramid.hpp>
#include <opencv2\reg\mapprojec.hpp>
using namespace cv;
using namespace cv::reg;
int main(int, char**)
{
Mat img1 = imread("D:\\SO\\temp\\chess.JPG");
Mat img2 = imread("D:\\SO\\temp\\chess2.png");
img1.convertTo(img1, CV_64FC3);
img2.convertTo(img2, CV_64FC3);
MapperGradProj mapper;
MapperPyramid mappPyr(mapper);
Ptr<Map> mapPtr;
mappPyr.calculate(img1, img2, mapPtr);
Mat dest;
MapProjec* mapProj = dynamic_cast<MapProjec*>(mapPtr.get());
mapProj->normalize();
mapProj->inverseWarp(img2, dest);
// Show difference
Mat image1, image2;
img1.convertTo(image1, CV_32FC3);
img2.convertTo(image2, CV_32FC3);
cvtColor(image1, image1, CV_RGB2GRAY);
cvtColor(image2, image2, CV_RGB2GRAY);
Mat imgDiff;
img1.copyTo(imgDiff);
imgDiff -= img2;
imgDiff /= 2.f;
imgDiff += 128.f;
Mat imgSh;
imgDiff.convertTo(imgSh, CV_8UC3);
imshow("Diff", imgSh);
dest.convertTo(dest, CV_8UC3);
imshow("Dest", dest);
waitKey();
return 0;
}
关于c++ - 从静态图像中减去背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33900409/