Alors que trouver une différence entre 2 images OpenCV différence est plus grande que ce qui est censé être

je travaille avec OpenCV (dans Android NDK) et j'ai un problème. Je veux trouver des différences entre deux photos, et couper la différence. Toutefois, les résultats suivants ont fait une plus grande différence. J'ai utilisé des images de cette question CV-extrait des différences entre deux images . Et j'ai essayé de le résoudre, mais sans succès. Voici la sortie

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;

PREMIÈRE IMAGE enter image description here DEUXIÈME IMAGE enter image description here RÉSULTAT enter image description here

d'un autre côté , ce code me donne la sortie comme ceci

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: désolé pour aucun design

0
demandé sur Miloš Vukadinović 2017-12-22 10:02:02

3 réponses

mon résultat en 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)

mise à jour avec 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;
}

réponses similaires:

  1. CV-extrait différences entre deux images

  2. tout en trouvant un différence entre 2 images OpenCV différence est plus grande que ce qui est supposé être

3
répondu Silencer 2017-12-22 09:31:44

D'ici: CV - extrait différences entre deux 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;
        }
    }

puis effectuer la soustraction de l'arrière-plan.

0
répondu no_fate 2017-12-22 07:20:01

j'ai fait comme ça avec l'aide de @Silencer en conséquence j'ai eu le bon résultat. Espérons que cela aidera si quelqu'un a un problème similaire

      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;
0
répondu Miloš Vukadinović 2017-12-23 23:20:58