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
DEUXIÈME IMAGE
RÉSULTAT
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;
3 réponses
mon résultat en python:
# 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:
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.
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;