两个照片之间的差异在公差变量

时间:2016-12-13 13:47:05

标签: c++ visual-studio opencv image-processing pixels

我有两张照片: enter image description here  和enter image description here

我在这些照片之间得到了分歧。但是这些差异包括光线的变化,相机的抖动等等。我只想看到差异照片中的男人。我写了一个阈值,我成功了。但是这个阈值并不能纠正其他照片。由于我在stackoverflow中的声誉,我无法显示错误的示例。你可以在其他照片上运行我的代码,你可以看到这些疾病。我的代码如下。我怎么能做这个门槛?

 #include <Windows.h>
 #include <opencv\highgui.h>
 #include <iostream>
 #include <opencv2\opencv.hpp>
 using namespace cv;
using namespace std;
int main() {

Mat siyah;
Mat resim = imread("C:/Users/toshiba/Desktop/z.jpg", CV_LOAD_IMAGE_GRAYSCALE);
Mat resim2 = imread("C:/Users/toshiba/Desktop/t.jpg", CV_LOAD_IMAGE_GRAYSCALE);
if (resim.empty() || resim2.empty())
{
    cout << "Dosya Açılamadı " << "\n";
    return 0;
}
for (int i = 0; i < resim.rows; i++)
{
    for (int j = 0; j <resim.cols; j++)
    {
        if (resim.data[resim.channels()*(resim.cols*(i)+
            (j))] - resim2.data[resim2.channels()*(resim2.cols*(i)+
                (j))]>30) {
            resim.data[resim.channels()*(resim.cols*(i)+
                (j))] = 255;

        }
        else
            resim.data[resim.channels()*(resim.cols*(i)+
                (j))] = 0;


        //inRange(resim, 150, 255, siyah);
    }
}
//inRange(resim, 150, 255, siyah);
namedWindow("Resim", CV_WINDOW_NORMAL);
imshow("Resim", resim);
waitKey();

system("PAUSE");
waitKey();
return 0;
}

2 个答案:

答案 0 :(得分:0)

如果您的背景始终相同且包含对象的图片很少出现,那么您可以经常更新参考图像,以便从参考图像到要分析的图像的光照变化总是很小。然后,您可以测量/计算在计算图像差异时大多数时间将起作用的阈值。我不确定你的相机为什么会移动 - 它不固定吗?

答案 1 :(得分:0)

我使用Otsu thresholdingGrabCut algorithm制作了以下代码。它不使用任何预先设定的阈值,但我仍然不确定它对其他图像的效果如何(如果您提供更多图片进行测试)。代码是在Python中,但它主要包括调用OpenCV函数和填充矩阵,因此应该很容易转换为C ++或其他。您的图片的结果: enter image description here

仅在差异上使用Otsu就会给出以下掩码: enter image description here 腿很好,但其余的都搞砸了。但似乎没有误报,所以我把面具作为明确的前景,其他一切都作为可能的背景,并将它喂给GrabCut。

import cv2
import numpy as np

#read the empty background image and the image with the guy in it,
#convert them into float32, so we don't get integers overflow
img_empty = cv2.imread("000_empty.png", 0).astype(np.float32)
img_guy = cv2.imread("001_guy.jpg", 0).astype(np.float32)

#absolute difference -> back to uint8 for thresholding etc.
diff = np.abs(img_empty - img_guy).astype(np.uint8)

#otsu thresholding
ret2, th = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

#read our image again for GrabCut
img = cv2.imread("001_guy.jpg")

#fill GrabCut mask
mask = np.zeros(th.shape, np.uint8)
mask[th == 255] = cv2.GC_FGD #the value is GC_FGD (foreground) when our thresholded value is 255
mask[th == 0] = cv2.GC_PR_BGD #GC_PR_BGD (probable background) otherwise

#some internal stuff for GrabCut...
bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)

#run GrabCut
cv2.grabCut(img, mask, (0, 0, 1365, 767), bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_MASK)

#convert the `mask` we got from GrabCut into a binary mask,
#then apply it to the original image
mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
img = img*mask2[:,:,np.newaxis]

#save the results
cv2.imwrite("003_grabcut.jpg", img)