Manpreet Singh
Manpreet Singh

Reputation: 11

Rotating an image using imrotate but setting pixels outside of the image to non-zero

I am doing a project on Image Watermarking using Discrete Wavelet Transform. I have obtained the watermarked image, and now I am attacking the image with things like rotation. When I apply function imrotate to the watermarked image, all the pixels that are not included in the rotated image become zero as it is a property of imrotate. Due to this, I get very low PSNR between the original image and rotated watermarked image.

My question is this. I want to rotate the image but I also need to have high values of PSNR after rotation. Is there any method that after rotation, I am able to keep all or most of pixels from the rotated image that resembles those pixels of the original image?

Upvotes: 0

Views: 3360

Answers (2)

binarysta
binarysta

Reputation: 156

Rotate an image in MATLAB and change the backgound color

Here's the solution!

the final image result is here

    clc; clear;
    img=imread('cameraman.tif');

    padColor=128; %//the color you want for background

    %//one pixel padding for highlitghing the borders of image
    img=padarray(img,[1 1],padColor);


    rotated_img=imrotate(img,30); %//rotation

    [m,n]=size(rotated_img);%size of rotated image

    %//in two for-loops, coloring the rotated image until we see the border(specified earlier)
    for j=1:m                  
        for k=1:n
            if rotated_img(j,k)~= padColor
                rotated_img(j,k)=padColor;
            else
                break;
            end
        end
    end
    for j=m:-1:1
        for k=n:-1:1
            if rotated_img(j,k)~= padColor
                rotated_img(j,k)=padColor;
            else
                break;
            end
        end
    end


    xmin=2; ymin=2;
    width=m-1; height=n-1; 
    %//cropping the one-pixel padding that we had added before
    rotated_img=imcrop(rotated_img,[xmin ymin width height]);

    imshow(rotated_img);

Upvotes: 0

rayryeng
rayryeng

Reputation: 104545

That is a consequence with imrotate. When you rotate the image, the image gets padded with zeroes for pixels that weren't included in the result. However, one thing I can suggest is that you can fill in any pixels that weren't included with a constant value.... like the mean intensity of the image, provided that your image is grayscale.

I've done something similar in this post here: Convert angle quantitative data into qualitative images

I was given a base image and I had to rotate the image given a list of angles. When I rotated the image, I had to fill the background with white pixels.


Therefore, one good way to do that is to provide an image that is all logical true which is the same size as the original image. You would also rotate this image so that the rotated image has false pixels which signify that those aren't included in the rotation and true pixels signify that those are included. You would invert this mask so that you find all of the pixels in the final image that were not included in the rotation result. You can use this mask to index into the rotated image and substitute the zero pixels with the mean intensity. However, because you're finding the PSNR between different images, you'll probably want the rotated image to have the same dimensions as the original image, so make sure you specify the 'crop' flag when rotating. This will unfortunately remove some of the pixels after rotation but this is in order to keep the dimensions of the image the same as the original image.

Therefore, do something like this, given that your image is stored in A, and you want to rotate the image by an angle theta:

%// Define mask
mask = true(size(A));

%// Rotate original image
B = imrotate(A, theta, 'crop');

%// Rotate the mask and invert
maskR = ~imrotate(mask, theta, 'crop');

%// Find mean intensity of original image
meanI = mean(A(:));

%// Assign values in rotated result that are not included
%// with mean intensity
B(maskR) = meanI;

%// Show the images
figure; 
subplot(1,3,1); imshow(A); title('Original Image');
subplot(1,3,2); imshow(maskR); title('Rotated Mask');
subplot(1,3,3); imshow(B); title('Rotated Image');

Let's test this out. I'm going to use the cameraman.tif image that is part of MATLAB's image processing toolbox. This is what it looks like:

enter image description here

Therefore, with defining a rotation angle of 30 degrees counter-clockwise:

A = imread('cameraman.tif');
theta = 30;

This is what the results look like:

enter image description here


Upvotes: 2

Related Questions