에 대한 게시물은 (여기 CV_64F) 당신이 얻을 :
bool findValue(const cv::Mat &mat, double value) {
for(int i = 0;i < mat.rows;i++) {
const double* row = mat.ptr<double>(i);
if(std::find(row, row + mat.cols, value) != row + mat.cols)
return true;
}
return false;
}
(자세한 내용은 find docs 참조). 물론 매트 행을 벡터로 변환 한 다음 해당 벡터에서 std :: find를 사용하면 행 배열에 대한 포인터에서 직접 find를 사용하는 것보다 속도가 느립니다.
편집 : 좀 더 복잡한 데이터 유형에 그것을 테스트
template <class T>
bool findValue(const cv::Mat &mat, T value) {
for(int i = 0;i < mat.rows;i++) {
const T* row = mat.ptr<T>(i);
if(std::find(row, row + mat.cols, value) != row + mat.cols)
return true;
}
return false;
}
: : 좀 더 연구 후에는 제네릭을 개발하는 것은 매우 어려운 일이 아니다 놀라게
cv::Mat matDouble = cv::Mat::zeros(10, 10, CV_64F);
cv::Mat matRGB = cv::Mat(10, 10, CV_8UC3, cv::Scalar(255, 255, 255));
std::cout << findValue(matDouble, 0.0) << std::endl;
std::cout << findValue(matDouble,1.0) << std::endl;
std::cout << findValue(matRGB, cv::Scalar(255, 255, 255)) << std::endl;
std::cout << findValue(matRGB, cv::Scalar(255, 255, 254)) << std::endl;
그리고 무엇 나 출력은 다음과 같습니다.
1
0
0 // should be 1, right?
0
문제는 cv :: Scalar 크기 구조 때문입니다. 우리가 사용하는 생성자의 버전에 관계없이 (즉, 하나, 둘, 셋 또는 네 개의 인수) 크기는 일정합니다. 이것은 여전히 놀라운 구조이므로, 내 컴퓨터에서 크기는 32 바이트입니다 (기본적으로 cv :: Scalar는 double 형식이므로 double은 8 바이트이고 4 * 8 = 32입니다). 그래서 find는 엄격하게 잘못 되었기 때문에 배열의 요소 크기를 32 바이트로 가정하고 3 바이트 여야합니다.
그래서 std :: find와 함께 cv :: Scalar!를 사용하지 마십시오! 그러나 원시 데이터 형식이 훌륭하고 효율적으로 작동합니다.
EDIT2 (berak의 코멘트 후) :
예, 찾기와 이력서 :: Vec3b을 사용할 수 있으며 단순히 올바른 테스트보다 더 많은 테스트를하지 않은 있지만, 그것은 잘 작동 보인다 :
cv::Mat matRGB = cv::Mat(10, 10, CV_8UC3, cv::Scalar(255, 255, 255));
std::cout << findValue(matRGB, cv::Vec3b(255, 255, 255)) << std::endl;
std::cout << findValue(matRGB, cv::Vec3b(255, 255, 254)) << std::endl;
(여전히 Mat 생성자에서 Scalar를 사용해야하지만 매트는 제대로 초기화됩니다.) 이제 출력은 예상대로입니다 :
1
0
정확하게 'find element'는 무엇을 의미합니까? 바이너리 응답이 필요합니까 (예 : '17'이 포함되어 있습니까?)? 색인 목록? x, y 위치? 발생 카운트 ('i == 17)? – berak
매트에있는 대상의 x, y 위치 (내 경우에는 단지 1 차원 위치)를 원했습니다. @marol은 색인을 쉽게 얻기 위해 수정 될 수있는 이진 버전의 응답을 제공했습니다. –