2014-02-20 2 views
1

이미지 상단에 8X8 분리형 평균 필터를 적용하려고합니다. 필터는 2D 분리 가능합니다. 내가 matlab에에서 다음 코드를 변환하고있어sepFilter2D Opencv 예기치 않은 결과가

,

커널 = 것들 (N);
제로 파트가없는 전환 2에 대한 %
LimgLarge = padarray (Limg, [n n], 'circular');
LimgKer = conv2 (LimgLarge, Kernel, 'same')/(n^2);
LKerCorr = LimgKer (n + 1 : end-n, n + 1 : end-n);

첫 번째는 필터 크기로 이미지를 채우고, 2d를 상관시키고, 마지막으로 이미지 영역을 자릅니다.

지금, 나는라는 다음 명령보다, 내가 이미지를로드 한 OpenCV의

를 사용하여 C++에서 같은 일을 구현하기 위해 노력하고있어 나는 같은 결과를받을 것으로 예상

m_kernelSize = 8; 
m_kernelX = Mat::ones(m_kernelSize,1,CV_32FC1); 
m_kernelX = m_kernelX/m_kernelSize; 

m_kernelY = Mat::ones(1,m_kernelSize,CV_32FC1); 
m_kernelY = m_kernelY/m_kernelSize; 

sepFilter2D(m_logImage,m_filteredImage,m_logImage.depth(),m_kernelX,m_kernelY,Point(-1,-1),0,BORDER_REPLICATE); 

, 하지만 여전히 Matlab과 완전히 다른 결과를 얻고 있습니다.

필자는 이미지를 채우지 않고 상관 관계를 확인한 다음 이미지를 다시 자르지 않고 BORDER_REPLICATE 인수를 사용하여 동일한 결과를 예상했습니다.

btw, 나는 copyMakeBorder 함수를 알고 있지만 sepFilter2D가 영역을 단독으로 처리하기 때문에이를 사용하지는 않습니다. 당신이 코드가, 나는 두 가지 잠재적 인 결함을 볼 수 있습니다 보여 니펫을하기 전에 당신은 단지 이미지를로드하는 것을 때문에

어떤 도움은 매우

+2

원본 이미지, matlab 결과 및 OpenCV 결과를 업로드 할 수 있습니까? – scap3y

+0

물론, 몇 시간 걸리 겠지만 더미 이미지를 대신 사용할 수 있습니다 – TripleS

+0

"다른 결과"를 정의하십시오 –

답변

0

저는 Matlab을 한 줄씩 따라갔습니다. 실수는 다른 곳에서있었습니다.

어쨌든, 다음 두 가지 방법은 분리의 8x8 필터

sepFilter2D (m_logImage, m_filteredImage, m_logImage를 사용하여 8X8 필터를

// Big filter mode - now used only for debug mode 
m_kernel = Mat::ones(m_kernelSize,m_kernelSize,type); 
cv::Mat LimgLarge(m_logImage.rows + m_kernelSize*2, m_logImage.cols + m_kernelSize*2,m_logImage.depth()); 
cv::copyMakeBorder(m_logImage, LimgLarge, m_kernelSize, m_kernelSize, 
    m_kernelSize, m_kernelSize, BORDER_REPLICATE); 

// Big filter 
filter2D(LimgLarge,m_filteredImage,LimgLarge.depth(),m_kernel,Point(-1,-1),0,BORDER_CONSTANT); 
m_filteredImage = m_filteredImage/(m_kernelSize*m_kernelSize); 

cv::Rect roi(cv::Point(0+m_kernelSize,0+m_kernelSize),cv::Point(m_filteredImage.cols-m_kernelSize, m_filteredImage.rows-m_kernelSize)); 
cv::Mat croppedImage = m_filteredImage(roi); 
m_diffImage = m_logImage - croppedImage; 

둘째 방법을 사용하여 동일한 결과

를 반환한다. 깊이(), m_kernelX, m_kernelY, Point (-1, -1), 0, BORDER_REPLICATE);

m_filteredImage = m_filteredImage/(m_kernelSize * m_kernelSize);

0

을 감상 할 수있다.

먼저, 당신은 원본 이미지의 로딩과 코드 사이에 아무것도하지 않고 있다면, 당신의 원본 이미지 당신이 함수 인수 ddepthm_logImage.depth()로 설정하기 때문에, 당신은 또한, 8 비트 이미지하고 것 8 비트 대상 이미지를 요청합니다.

그러나 documentation of sepFilter2D을 읽은 후에 이것이 src.depth()ddepth의 유효한 조합이라는 것을 확신하지 못합니다.

다음 줄을 사용하여 당신이 시도 할 수

sepFilter2D(m_logImage,m_filteredImage,CV_32F,m_kernelX,m_kernelY,Point(-1,-1),0,BORDER_REPLICATE); 

둘째, 당신은 단지 세 가지가 하나 개의 채널을 가지고하지 않도록 플래그 CV_LOAD_IMAGE_GRAYSCALE을 사용하여 소스 이미지를로드 있는지 확인합니다.

관련 문제