0

I'm working with OpenCV (in Android NDK) and I have a problem. I want to find differences between two pictures, and than cut the difference. However, following output made difference bigger. I used images from this question CV - Extract differences between two images . And I tried to solve it but unsuccessfully. Here is the output

Mat& backgroundImage = *(Mat*) addrRgba;
Mat& currentImage = *(Mat*) addrRgba2;
Mat diffImage;
absdiff(backgroundImage, currentImage, diffImage);
Mat mask=currentImage.clone();

          float threshold = 30.0f;
            float dist;

          for(int j=0; j<diffImage.rows; ++j)
              for(int i=0; i<diffImage.cols; ++i)
              {
                  if(diffImage.at<cv::Vec3b>(j,i)==Vec3b(0,0,0)){
                    Point center( i , j);
                   circle (mask,center,1,Scalar( 255, 255, 255 ),-1,9,0);
                  }

              }

               currentImage=mask;

FIRST IMAGE enter image description here SECOND IMAGE enter image description here RESULT enter image description here

On the other hand , this code gives me output like this

Mat& backgroundImage = *(Mat*) addrRgba;
Mat& currentImage = *(Mat*) addrRgba2;
Mat diffImage;

      absdiff(backgroundImage, currentImage, diffImage);
      Mat gray;

      cvtColor(diffImage,gray, COLOR_BGR2GRAY);

      equalizeHist( gray, gray );
      Mat mask=currentImage.clone();
      cvtColor(mask,mask, COLOR_BGR2GRAY);
      float threshold = 30.0f;
      float dist;

                for(int j=0; j<gray.rows; ++j)
                    for(int i=0; i<gray.cols; ++i)
                    {
                        cv::Vec3b pix = gray.at<cv::Vec3b>(j,i);

                        if(pix==Vec3b(0,0,0)){

                              Point center( i , j);
                              circle (mask,center,1,Scalar( 255, 255, 255 ),-1,9,0);
                        }
                    }
                    Mat maskedImage;
                diffImage.copyTo(maskedImage,mask);
               currentImage=mask;

enter image description here ps:sorry for no design

3 Answers3

3

My result in python:

enter image description here

# 2017.12.22 15:48:03 CST
# 2017.12.22 16:12:26 CST

import cv2
import numpy as np

img1 = cv2.imread("img1.png")
img2 = cv2.imread("img2.png")
diff = cv2.absdiff(img1, img2)
gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)

## find the nozero regions in the gray
imask =  gray>0

## create a Mat like img2
canvas = np.zeros_like(img2, np.uint8)

## set mask 
canvas[imask] = img2[imask]
cv2.imwrite("result.png", canvas)

Update with c++

//! 2017.12.22 17:05:18 CST
//! 2017.12.22 17:22:32 CST

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main() {

    Mat img1 = imread("img1.png");
    Mat img2 = imread("img2.png");

    // calc the difference
    Mat diff;
    absdiff(img1, img2, diff);

    // Get the mask if difference greater than th
    int th = 10;  // 0
    Mat mask(img1.size(), CV_8UC1);
    for(int j=0; j<diff.rows; ++j) {
        for(int i=0; i<diff.cols; ++i){
            cv::Vec3b pix = diff.at<cv::Vec3b>(j,i);
            int val = (pix[0] + pix[1] + pix[2]);
            if(val>th){
                mask.at<unsigned char>(j,i) = 255;
            }
        }
    }

    // get the foreground
    Mat res;
    bitwise_and(img2, img2, res, mask);

    // display
    imshow("res", res);
    waitKey();
    return 0;
}

Similar answers:

  1. CV - Extract differences between two images

  2. While finding a difference between 2 pictures OpenCV difference is bigger than it is supposed to be

Kinght 金
  • 17,681
  • 4
  • 60
  • 74
  • Thanks for answer, however I am not familiar with python Opencv programming. It would be great if you could explain me what those three lines do imask = gray>0 canvas = np.zeros_like(img2, np.uint8) canvas[imask] = img2[imask] – Miloš Vukadinović Dec 22 '17 at 08:58
  • Thanks man you are so kind , however this code gives me the same pic I had but with less th difference. It is probably a problem with Android and NDK or pointers beucase I'm working in Android Studio – Miloš Vukadinović Dec 22 '17 at 09:59
  • @MilošVukadinović Then I don't know. It works for me on PC – Kinght 金 Dec 22 '17 at 10:37
0

From here: CV - Extract differences between two images

cv::Mat diffImage;
cv::absdiff(backgroundImage, currentImage, diffImage);

cv::Mat foregroundMask = cv::Mat::zeros(diffImage.rows, diffImage.cols, CV_8UC1);

float threshold = 30.0f;
float dist;

for(int j=0; j<diffImage.rows; ++j)
    for(int i=0; i<diffImage.cols; ++i)
    {
        cv::Vec3b pix = diffImage.at<cv::Vec3b>(j,i);

        dist = (pix[0]*pix[0] + pix[1]*pix[1] + pix[2]*pix[2]);
        dist = sqrt(dist);

        if(dist>threshold)
        {
            foregroundMask.at<unsigned char>(j,i) = 255;
        }
    }

Then make background subtraction.

no_fate
  • 1,625
  • 14
  • 22
0

I did it like this with a help of @Silencer as a concequence I got the right result. Hope this will help if anyone have a similar problem

      Mat& backgroundImage = *(Mat*) addrRgba;
      Mat& currentImage = *(Mat*) addrRgba2;
      Mat HSV_currentImage;
      Mat HSVbackgroundImagebg;
      Mat diffImage;
      cvtColor(backgroundImage, HSVbackgroundImagebg, CV_BGR2HSV);
      cvtColor(currentImage, HSV_currentImage, CV_BGR2HSV);
      absdiff(HSVbackgroundImagebg, HSV_currentImage, diffImage);
      Mat mask(diffImage.size(), CV_8UC1);
                float threshold = 30.0f;
                float dist;

                for(int j=0; j<diffImage.rows; ++j)
                    for(int i=0; i<diffImage.cols; ++i)
                    {
                        Vec3b pix = diffImage.at<cv::Vec3b>(j,i);
                        dist = (pix[0]*pix[0] + pix[1]*pix[1] + pix[2]*pix[2]);
                                    dist = sqrt(dist);
                        if(dist>threshold){
                          mask.at<unsigned char>(j,i) = 255;
                        }

                    }

      Mat res;
      bitwise_and(currentImage, currentImage, res, mask);
      currentImage=res;