[EDIT] Opracowałem kod do porównywania obrazów. Ta pasująca część jest nadal trochę wadliwa i chciałabym trochę wsparcia. Projekt można znaleźć na stronie - GitHub.Porównanie obrazów OpenCV w systemie Android
mam te dwa obrazy img1 i img2:
Kiedy należy użyć następującego polecenia w OpenCV
Mat img1 = Highgui.imread("mnt/sdcard/IMG-20121228.jpg");
Mat img2 = Highgui.imread("mnt/sdcard/IMG-20121228-1.jpg");
try{
double l2_norm = Core.norm(img1, img2);
tv.setText(l2_norm+"");
} catch(Exception e) {
//image is not a duplicate
}
mogę dostać podwójną wartość dla l2_norm. Ta podwójna wartość zmienia się dla duplikatów par obrazów. Ale jeśli obrazy są różne, zostanie zgłoszony wyjątek. Czy w ten sposób identyfikuję zduplikowane obrazy? A może jest lepsza metoda? Zrobiłem wiele badań i nie mogłem znaleźć naprawdę przekonującej odpowiedzi. Chciałbym kodu i wyjaśnienia, jak porównać dwa obrazy i uzyskać wartość boolowską true
lub false
w zależności od obrazów.
EDIT
Scalar blah= Core.sumElems(img2);
Scalar blah1=Core.sumElems(img1);
if(blah.equals(blah1))
{
tv.setText("same image");
}
}
Próbowałem to, ale stan if
nigdy nie jest zadowolony. Zakładam, że jest kilka różnic, ale nie ma funkcji compare
dla Scalar
. Co ja robię?
EDIT
try{
Scalar blah= Core.sumElems(img2);
Scalar blah1=Core.sumElems(img1);
String b=blah.toString();
String b1=blah1.toString();
System.out.println(b+" "+b1);
double comp=b.compareTo(b1);
tv.setText(""+comp);
}
Metoda ta jest ponownie wadliwy. Chociaż można go używać do porównywania obrazów z przyzwoitą dokładnością, nie działa, gdy obrazy mają różne rozmiary.
Gdy obrazy są w różnych rozmiarach i wydrukować wartości skalarne uzyskać to:
[9768383.0, 1.0052889E7, 1.0381814E7, 0.0] [1.5897384E7, 1.6322252E7, 1.690251E7, 0.0]
Różnice pomiędzy drugim i trzecim numerów chociaż nie wiele jest dość duży w porównaniu z sytuacją, gdy obrazy same rozmiar są porównywane. Pierwsza liczba cierpi najwięcej zmian.
Jaki byłby najlepszy najszybszy sposób porównania zawartości dwóch obrazów?
[EDIT]
Używam kod znalazłem here.
Co nie jestem w stanie dowiedzieć się, jak zainicjować MatOfKeyPoint
keypoints
zmienne i logoKeypoints
. Tu jest mój urywek kodu:
FeatureDetector detector = FeatureDetector.create(FeatureDetector.SURF);
//FeatureDetector detector = FeatureDetector.create(FeatureDetector.FAST);
//Imgproc.cvtColor(img1, img1, Imgproc.COLOR_RGBA2RGB);
//Imgproc.cvtColor(img2, img2, Imgproc.COLOR_RGBA2RGB);
DescriptorExtractor SurfExtractor = DescriptorExtractor
.create(DescriptorExtractor.SURF);
//extract keypoints
MatOfKeyPoint keypoints, logoKeypoints;
long time= System.currentTimeMillis();
detector.detect(img1, keypoints);
Log.d("LOG!", "number of query Keypoints= " + keypoints.size());
detector.detect(img2, logoKeypoints);
Log.d("LOG!", "number of logo Keypoints= " + logoKeypoints.size());
Log.d("LOG!", "keypoint calculation time elapsed" + (System.currentTimeMillis() -time));
//Descript keypoints
long time2 = System.currentTimeMillis();
Mat descriptors = new Mat();
Mat logoDescriptors = new Mat();
Log.d("LOG!", "logo type" + img2.type() + " intype" + img1.type());
SurfExtractor.compute(img1, keypoints, descriptors);
SurfExtractor.compute(img2, logoKeypoints, logoDescriptors);
Log.d("LOG!", "Description time elapsed" + (System.currentTimeMillis()- time2));
I oczywiście nie może zainicjować zmienne keypoints
i logoKeypoints
NULL bo będę odbierać wyjątku null pointer wtedy. Jak mogę je zainicjować?
Ten tutorial OpenCV ma nadzieję, że zawiera pewne informacje na ten temat; http://goo.gl/gwN6e. – harism
try-catch jest * nie * taki sam jak gdyby-else! Jeśli został zgłoszony wyjątek (catch catch), coś poszło nie tak! – sschrass
@SatelliteSD - Wiem o tym. Dlatego pytam, czy istnieje lepsza metoda. –