나는 그런 간단한 수표가 느리다는 것에 놀랍니다. 아마 당신은 그것을 효율적으로 코딩하지 않을 것입니다.
여기에는 간단한 코드가 있습니다. 그것은 최적의도 속도 나 메모리에, 그러나 확실히 그것의 위해서 코드 :
std::vector<cv::Mat> planes;
cv::split(image, planes);
cv::Mat mask = planes[0] == planes[1];
mask &= planes[1] == planes[2];
라인 수에, 여기 내 의견으로는 그것을 할 수있는 가장 빠른 방법이 될 것입니다 뭔가를 비교 이미지에
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <vector>
#include <sys/time.h> //gettimeofday
static
double
P_ellapsedTime(struct timeval t0, struct timeval t1)
{
//return ellapsed time in seconds
return (t1.tv_sec-t0.tv_sec)*1.0 + (t1.tv_usec-t0.tv_usec)/1000000.0;
}
int
main(int argc, char* argv[])
{
struct timeval t0, t1;
cv::Mat image = cv::imread(argv[1]);
assert(image.type() == CV_8UC3);
std::vector<cv::Mat> planes;
std::cout << "Image resolution=" << image.rows << "x" << image.cols << std::endl;
gettimeofday(&t0, NULL);
cv::split(image, planes);
cv::Mat mask = planes[0] == planes[1];
mask &= planes[1] == planes[2];
gettimeofday(&t1, NULL);
std::cout << "Time using split: " << P_ellapsedTime(t0, t1) << "s" << std::endl;
cv::Mat mask2 = cv::Mat::zeros(image.size(), CV_8U);
unsigned char *imgBuf = image.data;
unsigned char *maskBuf = mask2.data;
gettimeofday(&t0, NULL);
for (; imgBuf != image.dataend; imgBuf += 3, maskBuf++)
*maskBuf = (imgBuf[0] == imgBuf[1] && imgBuf[1] == imgBuf[2]) ? 255 : 0;
gettimeofday(&t1, NULL);
std::cout << "Time using loop: " << P_ellapsedTime(t0, t1) << "s" << std::endl;
cv::namedWindow("orig", 0);
cv::imshow("orig", image);
cv::namedWindow("mask", 0);
cv::imshow("mask", mask);
cv::namedWindow("mask2", 0);
cv::imshow("mask2", mask2);
cv::waitKey(0);
}
벤치 (병렬 처리없이) :
이
Image resolution=3171x2179
Time using split: 0.06353s
Time using loop: 0.029044s
분할 이미지 I -> (A, B, C)를 확인한 다음 [(A-B) + (A-C)] == 0을 확인하는 것은 어떻습니까? (이미지를 서명 된 형식으로 먼저 변환하십시오). 당신은 pixel by pixel을 피할 것입니다. –
또는; 이미지를 분할하고 absdiff를 사용하고 이미지를 임계 값으로 설정합니다. – Nallath
흠. R == G == B이면 2R-G-B = 0. 2R-G-B를 계산 한 다음 countNonZero를 사용하는 것은 어떻습니까? 단지 직감. – GilLevi