Mam dwa wystąpienia cv :: Mat: m1 i m2. Są tego samego rodzaju i rozmiarów liczbowych. Czy istnieje funkcja OpenCV, która zwraca, czy macierze są identyczne (mają wszystkie te same wartości)?sposób sprawdzenia, czy dwie macierze są identyczne w OpenCV
Odpowiedz
Użyj cv::compare w połączeniu z cv::countNonZero.
SO pytanie, które może pomóc dalej OpenCV compare two images and get different pixels
Jak wspomniano przez Acme, można użyć cv::compare
choć nie jest tak czysty, jak można mieć nadzieję.
W poniższym przykładzie cv::compare
nazywa przy użyciu !=
operator:
// Get a matrix with non-zero values at points where the
// two matrices have different values
cv::Mat diff = a != b;
// Equal if no elements disagree
bool eq = cv::countNonZero(diff) == 0;
Prawdopodobnie byłoby szybciej po prostu iterację porównując elementy chociaż? Jeśli znasz typ można użyć funkcji STL equal:
bool eq = std::equal(a.begin<uchar>(), a.end<uchar>(), b.begin<uchar>());
'bool eq = cv :: countNonZero (a! = B) == 0;'. Myślę, że jest to rozsądnie czyste. Najbardziej irytujące jest to, że musisz odwrócić operator porównania w porównaniu do tego, co naprawdę chcesz wiedzieć ('! =' Zamiast '== '), ponieważ nie ma funkcji' countZero() '. – nobar
Cv :: Mat może, ale nie musi ciągły, nie jestem pewien, czy bajty dopełnienia każdego wiersza mają tę samą wartość. – StereoMatching
Tak, ale wierzę, że iteratory Mat zajmują się tym za Ciebie? http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-begin –
Jak wspomniano przez Acme i Tim, można użyć cv::compare
. Jest to kod używam porównać mój cv::Mat
:
bool matIsEqual(const cv::Mat mat1, const cv::Mat mat2){
// treat two empty mat as identical as well
if (mat1.empty() && mat2.empty()) {
return true;
}
// if dimensionality of two mat is not identical, these two mat is not identical
if (mat1.cols != mat2.cols || mat1.rows != mat2.rows || mat1.dims != mat2.dims) {
return false;
}
cv::Mat diff;
cv::compare(mat1, mat2, diff, cv::CMP_NE);
int nz = cv::countNonZero(diff);
return nz==0;
}
Ważne jest, aby wyróżniać się, że funkcja cv::countNonZero
only works with cv::Mat
of one channel, więc jeśli trzeba porównać dwa cv::Mat
zdjęć musisz najpierw przekonwertować swojej cv::Mat
w ten sposób:
Mat gray1, gray2;
cvtColor(InputMat1, gray1, CV_BGR2GRAY);
cvtColor(InputMat2, gray2, CV_BGR2GRAY);
gdzie InputMat1
i InputMat2
są cv::Mat
chcesz porównać. Po tym można wywołać funkcję:
bool equal = matsEqual(gray1, gray2);
Wziąłem ten kod z tej strony: OpenCV: compare whether two Mat is identical
Mam nadzieję, że to pomoże.
Konwersja obrazów na skalę szarości powoduje utratę informacji i potencjalnie może spowodować, że identyczne obrazy dwukolorowe będą początkowo inne. – Antonio
Jest to kod używam porównać rodzajowe (nie w zależności od wymiarów i rodzaju elementów) cv::Mat
przypadki:
bool matIsEqual(const cv::Mat Mat1, const cv::Mat Mat2)
{
if(Mat1.dims == Mat2.dims &&
Mat1.size == Mat2.size &&
Mat1.elemSize() == Mat2.elemSize())
{
if(Mat1.isContinuous() && Mat2.isContinuous())
{
return 0==memcmp(Mat1.ptr(), Mat2.ptr(), Mat1.total()*Mat1.elemSize());
}
else
{
const cv::Mat* arrays[] = {&Mat1, &Mat2, 0};
uchar* ptrs[2];
cv::NAryMatIterator it(arrays, ptrs, 2);
for(unsigned int p = 0; p < it.nplanes; p++, ++it)
if(0!=memcmp(it.ptrs[0], it.ptrs[1], it.size*Mat1.elemSize()))
return false;
return true;
}
}
return false;
}
Nie rozumiem, dlaczego cv::Mat
nie ma operatora ==
według tego realizacja.
Używam tego:
bool areEqual(const cv::Mat& a, const cv::Mat& b) {
cv::Mat temp;
cv::bitwise_xor(a,b,temp); //It vectorizes well with SSE/NEON
return !(cv::countNonZero(temp));
}
Jeśli trzeba zrobić tę operację wiele razy, można zrobić to w klasie, mają temp
jako członka i zapobiec obraz ma zostać przydzielona za każdym razem. Szczegóły: zmień wartość temp
, aby areEqual
mogła być metodą const
.
Pamiętaj jednak, że cv::countNonZero
only works with cv::Mat
of one channel. To przesada, ale w takim przypadku można użyć cv::split
, aby podzielić każdy kanał na osobne obrazy i wykonać na nich cv::countNonZero
.
następuje będzie działać również matryc wielokanałowych:
bool isEqual = (sum(img1 != img2) == Scalar(0,0,0,0));
Ponieważ sum przyjmuje matryce z 1 do 4 kanałów i zwraca Scalar
, w którym element w [0] jest wynikiem sumy dla pierwszego kanału i tak dalej.
Innym sposobem, za pomocą pojedynczej funkcji byłoby użyć:
bool areIdentical = !cv::norm(img1,img2,NORM_L1);
Ponieważ norma L1 jest obliczane jako ∑I|img1(I)−img2(I)|
referencyjny: OpenCV norm
- 1. Jak połączyć dwie macierze w Python OpenCV?
- 2. Dwie identyczne daty JavaScript nie są równe
- 3. Powtarzaj jednocześnie dwie macierze.
- 4. Agregacja MongoDB: łącz dwie macierze
- 5. Czy istnieje sposób sprawdzenia, czy dwa elementy DOM są równe?
- 6. Wektoryzowany sposób obliczania iloczynu wierszowego dwie macierze z Scipy
- 7. W jaki sposób dwa identyczne ciągi nie są sobie równe?
- 8. Jak sprawdzić, czy wszystkie wartości w tablicy są identyczne?
- 9. Czy istnieje sposób sprawdzenia, czy dwie kolekcje zawierają te same elementy, niezależnie od kolejności?
- 10. Jak mogę zintegrować dwie macierze danych 1-D w Pythonie?
- 11. Skuteczny sposób sprawdzenia, czy dwie posortowane listy zawierają ten sam element Java.
- 12. Jak mogę sprawdzić, czy wszystkie elementy tablicy są identyczne w Perlu?
- 13. Najlepszy sposób sprawdzenia, czy usługa zawiesiła się
- 14. Sprawdź, czy dwie macierze mają tę samą zawartość (w dowolnej kolejności).
- 15. Czy porty docelowe i źródłowe SSH są identyczne (porty symetryczne)?
- 16. Sprawdzanie, czy dwie liczby są wzajemnie permutacyjne?
- 17. Sprawdź, czy dwie funkcje std :: są równe
- 18. Czy te programy obsługi zdarzeń uruchamiania są identyczne?
- 19. wykryć, czy dwie ścieżki są takie same
- 20. Sortuj dwie macierze o różnych wartościach zachowując oryginalny parowanie
- 21. Java - Najszybszy sposób sprawdzenia, czy URL istnieje
- 22. Czy istnieje sposób sprawdzenia, czy zmienna jest zdefiniowana w Javie?
- 23. pytoniczny sposób sprawdzenia, czy coś istnieje?
- 24. sposób sprawdzenia, czy blok dispatch_async zakończył działanie
- 25. Co sprawia, że te dwie ramki danych R nie są identyczne?
- 26. Czy istnieje lepszy sposób sprawdzenia, czy plik jest zapisywany?
- 27. Czy są jakieś bezpłatne biblioteki klasy OpenCV?
- 28. Połączyć dwie macierze i zamówić nową tablicę według daty
- 29. Czy istnieje sposób sprawdzenia, czy operacja OpenGL została zakończona?
- 30. Czy istnieje sposób sprawdzenia, czy odebrano transmisje LocalBroadcastManager?
Byłam jedną edycję odpowiedzi, ponieważ był niekompletne, ale muszę powiedzieć, że 'cv :: countNonZero' nie działa dla obrazów wielokanałowych. – Antonio