2017-11-21 3 views
1

matlab에서 이미지 스케일링을위한 바이 큐빅 보간을 구현하려고합니다. 문제는 회색 음영 이미지에서 제대로 작동한다는 것입니다. 그러나 컬러 이미지의 경우 회색 음영으로 나타납니다. 문제의 원인을 알려주십시오. 감사합니다.바이 큐빅 (Bicubic) 보간 matlab 구현은 그레이 스케일 이미지에만 적용됩니다.

bicubic interpoaltion의 경우 그라디언트가 들어있는 행렬을 사용했습니다. matix는 https://en.wikipedia.org/wiki/Bicubic_interpolation에서 찾을 수 있습니다.

여기 내 코드입니다.

input_image = im2double(imread('peppers.png')); 
       x_res = 700; 
       y_res = 700; 

       imshow(input_image, []); 


       M_inv = [ 
       1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0; 
       0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0; 
       -3,3,0,0,-2,-1,0,0,0,0,0,0,0,0,0,0; 
       2,-2,0,0,1,1,0,0,0,0,0,0,0,0,0,0; 
       0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0; 
       0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0; 
       0,0,0,0,0,0,0,0,-3,3,0,0,-2,-1,0,0; 
       0,0,0,0,0,0,0,0,2,-2,0,0,1,1,0,0; 
       -3,0,3,0,0,0,0,0,-2,0,-1,0,0,0,0,0; 
       0,0,0,0,-3,0,3,0,0,0,0,0,-2,0,-1,0; 
       9,-9,-9,9,6,3,-6,-3,6,-6,3,-3,4,2,2,1; 
       -6,6,6,-6,-3,-3,3,3,-4,4,-2,2,-2,-2,-1,-1; 
       2,0,-2,0,0,0,0,0,1,0,1,0,0,0,0,0; 
       0,0,0,0,2,0,-2,0,0,0,0,0,1,0,1,0; 
       -6,6,6,-6,-4,-2,4,2,-3,3,-3,3,-2,-1,-2,-1; 
       4,-4,-4,4,2,2,-2,-2,2,-2,2,-2,1,1,1,1 
       ]; 

       I = input_image; 






       [j k c] = size(I); 

       %{ 
       if c > 1 
        I = double(rgb2gray(I)); 
       end 

       %} 

       x_new = x_res; 
       y_new = y_res; 

       x_scale = x_new./(j-1); 
       y_scale = y_new./(k-1); 

       temp_image = zeros(x_new,y_new); 

       Ix = double(zeros(j,k)); 
       for count1 = 1:j 
        for count2 = 1:k 
         if((count2==1) || (count2==k)) 
          Ix(count1,count2)=0; 
         else 
          Ix(count1,count2)=(0.5).*(I(count1,count2+1)-I(count1,count2-1)); 
         end 
        end 
       end 

       Iy = double(zeros(j,k)); 
       for count1 = 1:j 
        for count2 = 1:k 
         if((count1==1) || (count1==j)) 
          Iy(count1,count2)=0; 
         else 
          Iy(count1,count2)=(0.5).*(I(count1+1,count2)-I(count1-1,count2)); 
         end 
        end 
       end 

       Ixy = double(zeros(j,k)); 
       for count1 = 1:j 
        for count2 = 1:k 
         if((count1==1) || (count1==j) || (count2==1) || (count2==k)) 
          Ixy(count1,count2)=0; 
         else 
          Ixy(count1,count2)=(0.25).*((I(count1+1,count2+1)+I(count1-1,count2-1)) - (I(count1+1,count2-1)+I(count1-1,count2+1))); 
         end 
        end 
       end 

       for count1 = 0:x_new-1 
        for count2 = 0:y_new-1 

        W = -(((count1./x_scale)-floor(count1./x_scale))-1); 
        H = -(((count2./y_scale)-floor(count2./y_scale))-1); 

        I11_index = [1+floor(count1./x_scale),1+floor(count2./y_scale)]; 
        I21_index = [1+floor(count1./x_scale),1+ceil(count2./y_scale)]; 
        I12_index = [1+ceil(count1./x_scale),1+floor(count2./y_scale)]; 
        I22_index = [1+ceil(count1./x_scale),1+ceil(count2./y_scale)]; 

        I11 = I(I11_index(1),I11_index(2)); 
        I21 = I(I21_index(1),I21_index(2)); 
        I12 = I(I12_index(1),I12_index(2)); 
        I22 = I(I22_index(1),I22_index(2)); 

        Ix11 = Ix(I11_index(1),I11_index(2)); 
        Ix21 = Ix(I21_index(1),I21_index(2)); 
        Ix12 = Ix(I12_index(1),I12_index(2)); 
        Ix22 = Ix(I22_index(1),I22_index(2)); 

        Iy11 = Iy(I11_index(1),I11_index(2)); 
        Iy21 = Iy(I21_index(1),I21_index(2)); 
        Iy12 = Iy(I12_index(1),I12_index(2)); 
        Iy22 = Iy(I22_index(1),I22_index(2)); 

        Ixy11 = Ixy(I11_index(1),I11_index(2)); 
        Ixy21 = Ixy(I21_index(1),I21_index(2)); 
        Ixy12 = Ixy(I12_index(1),I12_index(2)); 
        Ixy22 = Ixy(I22_index(1),I22_index(2)); 

        beta = [I11 I21 I12 I22 Ix11 Ix21 Ix12 Ix22 Iy11 Iy21 Iy12 Iy22 Ixy11 Ixy21 Ixy12 Ixy22]; 




        alpha = M_inv*beta'; 
        temp_p=0; 
        for count3 = 1:16 
         w_temp = floor((count3-1)/4); 
         h_temp = mod(count3-1,4); 

         temp_p = temp_p + alpha(count3).*((1-W)^(w_temp)).*((1-H)^(h_temp)); 
        end 

        temp_image(count1+1,count2+1)=temp_p; 
        end 
       end 

       output_image = temp_image; 


       figure; 
       imshow(output_image); 
+0

. 각 채널을 반복하지 않습니다 (즉, '크기'출력에 'c'변수를 사용하지 않는 경우). – rayryeng

+0

채널을 어떻게 사용하고 어떻게 정수 c를 사용해야하는지 설명해 주시겠습니까? 미리 감사드립니다. – Dick

답변

1

코드를 조정해야 각 채널에서 보간을 수행 할 수 있습니다. 간단히 말하자면, 각각의 채널을 I으로 만들 필요가 있습니다. output_image을 만들면 여러 개의 채널이 있고 각 채널을 개별적으로 반복 할 수 있습니다. 이러한 변화와

, 우리는 따라서이 있습니다

코드는 그것이 그레이 스케일 이미지입니다 가정하기 때문이다
input_image = im2double(imread('peppers.png')); 
x_res = 700; 
y_res = 700; 

imshow(input_image, []); 

% input_image  - an image on which to perform bicubic interpolation 
% x_res   - the new horizontal dimensions (in pixels) 
% y_res   - the new vertical dimensions (in pixels) 
%Define the inverted weighting matrix, M^(-1), no need to recalculate it 
%ever again 


M_inv = [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0; 
     0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0; 
     -3,3,0,0,-2,-1,0,0,0,0,0,0,0,0,0,0; 
     2,-2,0,0,1,1,0,0,0,0,0,0,0,0,0,0; 
     0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0; 
     0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0; 
     0,0,0,0,0,0,0,0,-3,3,0,0,-2,-1,0,0; 
     0,0,0,0,0,0,0,0,2,-2,0,0,1,1,0,0; 
     -3,0,3,0,0,0,0,0,-2,0,-1,0,0,0,0,0; 
     0,0,0,0,-3,0,3,0,0,0,0,0,-2,0,-1,0; 
     9,-9,-9,9,6,3,-6,-3,6,-6,3,-3,4,2,2,1; 
     -6,6,6,-6,-3,-3,3,3,-4,4,-2,2,-2,-2,-1,-1; 
     2,0,-2,0,0,0,0,0,1,0,1,0,0,0,0,0; 
     0,0,0,0,2,0,-2,0,0,0,0,0,1,0,1,0; 
     -6,6,6,-6,-4,-2,4,2,-3,3,-3,3,-2,-1,-2,-1; 
     4,-4,-4,4,2,2,-2,-2,2,-2,2,-2,1,1,1,1 
     ]; 

%Make a copy of the input image 
%I = input_image; % Ray: Not needed here 

%Determine the dimensions of the source image 
%Note that we will have three values - width, height, and the number 
%of color vectors, 3 
[j k c] = size(input_image); % Ray: Change 

%Specify the new image dimensions we want for our larger output image 
x_new = x_res; 
y_new = y_res; 
%Determine the ratio of the old dimensions compared to the new dimensions 
%Referred to as S1 and S2 in my tutorial 
x_scale = x_new./(j-1); 
y_scale = y_new./(k-1); 

% Change by Ray - Declare new output image here with c channels 
output_image = zeros(x_new, y_new, c); 

% Change by Ray - Now loop through each channel 
for z = 1 : c 
    %Declare and initialize an output image buffer 
    temp_image = zeros(x_new,y_new); 

    % New - Change by Ray. Access the right channel 
    I = input_image(:,:,z); 

    Ix = double(zeros(j,k)); 
    for count1 = 1:j 
     for count2 = 1:k 
      if((count2==1) || (count2==k)) 
       Ix(count1,count2)=0; 
      else 
       Ix(count1,count2)=(0.5).*(I(count1,count2+1)-I(count1,count2-1)); 
      end 
     end 
    end 

    Iy = double(zeros(j,k)); 
    for count1 = 1:j 
     for count2 = 1:k 
      if((count1==1) || (count1==j)) 
       Iy(count1,count2)=0; 
      else 
       Iy(count1,count2)=(0.5).*(I(count1+1,count2)-I(count1-1,count2)); 
      end 
     end 
    end 

    Ixy = double(zeros(j,k)); 
    for count1 = 1:j 
     for count2 = 1:k 
      if((count1==1) || (count1==j) || (count2==1) || (count2==k)) 
       Ixy(count1,count2)=0; 
      else 
       Ixy(count1,count2)=(0.25).*((I(count1+1,count2+1)+I(count1-1,count2-1)) - (I(count1+1,count2-1)+I(count1-1,count2+1))); 
      end 
     end 
    end 

    for count1 = 0:x_new-1 
     for count2 = 0:y_new-1 
      %Calculate the normalized distance constants, h and w 
      W = -(((count1./x_scale)-floor(count1./x_scale))-1); 
      H = -(((count2./y_scale)-floor(count2./y_scale))-1); 
      %Determine the indexes/address of the 4 neighbouring pixels from 
      %the source data/image 
      I11_index = [1+floor(count1./x_scale),1+floor(count2./y_scale)]; 
      I21_index = [1+floor(count1./x_scale),1+ceil(count2./y_scale)]; 
      I12_index = [1+ceil(count1./x_scale),1+floor(count2./y_scale)]; 
      I22_index = [1+ceil(count1./x_scale),1+ceil(count2./y_scale)]; 
      %Calculate the four nearest function values 
      I11 = I(I11_index(1),I11_index(2)); 
      I21 = I(I21_index(1),I21_index(2)); 
      I12 = I(I12_index(1),I12_index(2)); 
      I22 = I(I22_index(1),I22_index(2)); 
      %Calculate the four nearest horizontal derivatives 
      Ix11 = Ix(I11_index(1),I11_index(2)); 
      Ix21 = Ix(I21_index(1),I21_index(2)); 
      Ix12 = Ix(I12_index(1),I12_index(2));     
      Ix22 = Ix(I22_index(1),I22_index(2)); 
      %Calculate the four nearest vertical derivatives 
      Iy11 = Iy(I11_index(1),I11_index(2)); 
      Iy21 = Iy(I21_index(1),I21_index(2)); 
      Iy12 = Iy(I12_index(1),I12_index(2)); 
      Iy22 = Iy(I22_index(1),I22_index(2)); 
      %Calculate the four nearest cross derivatives 
      Ixy11 = Ixy(I11_index(1),I11_index(2)); 
      Ixy21 = Ixy(I21_index(1),I21_index(2)); 
      Ixy12 = Ixy(I12_index(1),I12_index(2)); 
      Ixy22 = Ixy(I22_index(1),I22_index(2)); 
      %Create our beta-vector 
      beta = [I11 I21 I12 I22 Ix11 Ix21 Ix12 Ix22 Iy11 Iy21 Iy12 Iy22 Ixy11 Ixy21 Ixy12 Ixy22]; 

      alpha = M_inv*beta'; 
      temp_p=0; 
      for count3 = 1:16 
       w_temp = floor((count3-1)/4); 
       h_temp = mod(count3-1,4); 

       temp_p = temp_p + alpha(count3).*((1-W)^(w_temp)).*((1-H)^(h_temp)); 
      end 

      temp_image(count1+1,count2+1)=temp_p; 
     end 
    end 

    % New - Change by Ray - Assign to output channel 
    output_image(:,:,z) = temp_image; 
end 


figure; 
imshow(output_image); 
+0

답변 해 주셔서 감사합니다. 그러나 결과는 지금 블루스 스케일에 있습니다 – Dick

+0

죄송합니다, 오타. 나는'z'를 사용하려고했습니다. 방금 고쳤어. 지금 시도해보십시오. BTW, 코드 기여에 감사드립니다. 우리는 이제 바이 큐빅 보간법을 구현해야 하는지를 사람들에게 알려주는 정규 복제본을 가지고 있습니다. – rayryeng

+0

죄송하지만 다시 z로 그레이 스케일로 표시됩니다. – Dick

관련 문제