从静态图像中减去背景 [英] Substract background from static image

查看:217
本文介绍了从静态图像中减去背景的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有像国际象棋这样的棋盘游戏。我从鸟的视角拍摄了2张照片,例如:





图像的每个角都有一个标记 1 ,这有助于我扭曲2张图片,这样即使它们可能是从略有不同的角度拍摄的,看起来大致相同。



这些图像中的一个将所有棋盘游戏数字放在某个位置,而另一个图像/图片则没有。



现在我在新图像中使用标记作为我的新角落并扭曲两张图片后,我想只得到棋盘游戏数字(所以基本上在经线之后) ,我希望有两张图片的区别)。



我现在的问题是一个简单的 mat1-mat2 cv :: substract 不起作用,因为它是精确的方式,如果这些图片的扭曲不是100%完美,结果根本没有帮助。



我想建立一个阵列,包括棋盘游戏人物的位置,这意味着如果我的想法能够奏效,我可能会更容易找到数字。 实现这一目标的正确方法是什么?在这种情况下,背景减法甚至是正确的做法吗?



(请注意,我不想将我的棋盘游戏数字与标记交换。角落上的标记对我来说已经是妥协了。






1 我期待着使用Aruco这个,如果你建议一个替代方案我也可以尝试一下。

解决方案

你应该看看



您可以注册它们,将其作为结果图像获取:





这两者之间存在差异:





您可以看到棋盘排列得非常好。注册已经处理了不同的观点。



代码:

  #include< opencv2 \opencv.hpp> 
#include< opencv2 \reg\mappergradproj.hpp>
#include< opencv2 \reg\mapperpyramid.hpp>
#include< opencv2 \reg\mapprojec.hpp>使用命名空间cv

;
使用命名空间cv :: reg;

int main(int,char **)
{
Mat img1 = imread(D:\\\\\\ temp \\chess。 JPG);
Mat img2 = imread(D:\\\\\\ temp\\chess2.png);

img1.convertTo(img1,CV_64FC3);
img2.convertTo(img2,CV_64FC3);

MapperGradProj mapper;
MapperPyramid mappPyr(mapper);

Ptr<地图> mapPtr;
mappPyr.calculate(img1,img2,mapPtr);

Mat dest;
MapProjec * mapProj = dynamic_cast< MapProjec *>(mapPtr.get());
mapProj-> normalize();
mapProj-> inverseWarp(img2,dest);

//显示差异

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();

返回0;
}


I have a board game like chess. I have 2 pictures of it shot from the bird perspective, like:

Each of the corners of the image have a marker1, that helps me to warp the 2 pictures so that even though they might have been shot from a slightly different perspective, they afterwards look mostly identical.

One of these images has all of the board game figures on it in a certain position and the other image/ picture does not.

Now after I use the markers as my new corners in a new image and warp both pictures, I want to only get have the board game figures (so basically after the warp, I want to have the difference of the two pictures).

My problem now is that a simple mat1-mat2 or cv::substract doesn't work since it's way to precise and if the warp of these pictures is not 100% perfect the result doesn't help at all.

I want to build an array, consisting of the positions of the board game figures, which means that if my idea would work I might have an easier time finding the figures. What would be the correct way to achieve this? Is background subtraction even the right thing to do in this case?

(Please note that I don't want to swap my board game figures with markers. The markers on the corners are already a compromise for me.


1I am looking forward to using Aruco for this, if you suggest an alternative I might as well try it.

解决方案

You should take a look at Image Registration.

I adapted the following code from the OpenCV samples

Given two different images of the chessboard (here I took you original image and warped a little bit)

You can register them, obtaining this as resulting image:

With this difference between the two:

You can see that the chessboard is aligned pretty well. The registration already takes care of the different point of views.

Code:

#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;
}

这篇关于从静态图像中减去背景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆