2016-03-07 4 views
1

Это функция, которую я написал для 2D извилины в C:Реализация 2D извилины в C

typedef struct PGMImage{ 
    int w; 
    int h; 
    int* data; 
}GrayImage; 

GrayImage Convolution2D(GrayImage image,GrayImage kernel){ 
    int aH,aW,bW,bH,r,c,x,y,xx,yy,X,Y; 
    int temp = 0; 
    GrayImage conv; 
    CreateGrayImage(&conv,image.w,image.h); 
    aH = image.h; 
    aW = image.w; 
    bH = kernel.h; 
    bW = kernel.w; 
    if(aW < bW || aH < bH){ 
     fprintf(stderr,"Image cannot have smaller dimensions than the blur kernel"); 
    } 

    for(r = aH-1;r >= 0;r--){ 
     for(c = aW-1;c >= 0;c--){ 
      temp = 0; 
      for(y = bH-1;y >= 0;y--){ 
       yy = bH - y -1; 
       for(x = bW-1;x >= 0;x--){ 
        xx = bW - x - 1; 
        X = c + (x - (bW/2)); 
        Y = r + (y - (bH/2)); 
        if(X >= 0 && X < aW && Y >= 0 && Y < aH){ 
         temp += ((kernel.data[(yy*bW)+xx])*(image.data[(Y*aW)+X])); 
        } 
       } 
      } 
      conv.data[(r*aW)+c] = temp; 
     } 
    } 
    return conv; 
} 

я воспроизвел эту функцию в Matlab и обнаружил, что он переоценивает значения для определенных пикселей по сравнению с регулярным Функция двумерной свертки в Matlab (conv2D). Я не могу понять, где я ошибаюсь в логике. Пожалуйста помоги.

EDIT: Вот стоковое изображение Я использую (512 * 512): https://drive.google.com/file/d/0B3qeTSY-DQRvdWxCZWw5RExiSjQ/view?usp=sharing

Вот ядро ​​(3 * 3): https://drive.google.com/file/d/0B3qeTSY-DQRvdlQzamcyVmtLVW8/view?usp=sharing

С помощью описанной выше функции я получаю

46465 46456 46564 
45891 46137 46158 
45781 46149 46030 

Но conv2 MatLab дает мне

46596 46618 46627 
46073 46400 46149 
45951 46226 46153 

для одних и тех же точек (строк: 239-241, цв: 316: 318)

Это код Matlab, я использую для сравнения значений:

pgm_img = imread('path\to\lena512.pgm'); 
kernel = imread('path\to\test_kernel.pgm'); 
sz_img = size(pgm_img); 
sz_ker = size(kernel); 
conv = conv2(double(pgm_img),double(kernel),'same'); 
pgm_img = padarray(pgm_img,floor(0.5*sz_ker),'both'); 
convolve = zeros(sz_img); 
for i=floor(0.5*sz_ker(1))+1:floor(0.5*sz_ker(1))+sz_img(1) 
    for j=floor(0.5*sz_ker(2))+1:floor(0.5*sz_ker(2))+sz_img(2) 
     startX = j - floor(sz_ker(2)/2); 
     startY = i - floor(sz_ker(1)/2); 
     endX = j + floor(sz_ker(2)/2); 
     endY = i + floor(sz_ker(1)/2); 
     block = pgm_img(startY:endY,startX:endX); 
     prod = double(block).*double(kernel); 
     convolve(i-floor(0.5*sz_ker(1)),j-floor(0.5*sz_ker(2))) = sum(sum(prod)); 
    end 
end 
disp(conv(239:241,316:318)); 
disp(convolve(239:241,316:318)); 
+1

Пожалуйста, дайте [mcve], который позволяет нам воспроизвести вашу проблему. Какое изображение и ядро ​​вы используете, и где вы ошибаетесь? – Daniel

+0

У нас возникает проблема с проприетарными образами. Можете ли вы запустить свою программу на общем фондовом изображении и указать на это вместо этого? –

+0

Серьезно попробуйте небольшой пример. С такими лагорными данными я бы никогда не заметил ошибку. – Daniel

ответ

0

Одна очевидная разница в том, что ваш c использует ints, в то время как в коде matlab используются удвоения. Измените свой код c на использование удвоений и посмотрите, все ли результаты по-другому.

0

Я создал библиотеку изображений Convolution для простых случаев изображения, которое представляет собой простой 2D Float Array.

Функция поддерживает произвольные ядра и проверяется на предмет реализации MATLAB.

Так что все необходимое на вашей стороне вызывает его сгенерированным ядром.

Вы можете использовать его сгенерированную DLL внутри MATLAB и увидеть, что он дает те же результаты, что и функции конвертации изображений MATLAB.

Image Convolution - GitHub.