bonapart3
bonapart3

Reputation: 519

Matlab select region from an image to alter

So I am implementing the reversible watermarking technique found in

"Reversible Visible Watermarking and Lossless Recovery of Original Images" by Y. Hu and B. Jeon.

So part of the embedding process involves inserting the watermark into the bit plane (MSB/7thSB) of a region of the image. The region's top left hand starting corner and size of region will be known.

I think I'm having a brain dead moment here, but I was wondering if anybody knew how to select this region from the image so that I can manipulate it?

Currently I have region_R = image_I(regionStartPoint + size_W); but I'm pretty sure this isn't right. After I get the region and manipulate it I must also put it back into the image, do I do this by something like outputImage = union(region_R, surroundingSpace) where surroundingspace is the image without the region?

Maybe I have got the wrong end of the stick here! Maybe I just need my for loops in my manipulation process to begin at the starting point? Or use imcrop but I didn't think that sounded quite right.

Thanks!

Upvotes: 2

Views: 301

Answers (1)

rayryeng
rayryeng

Reputation: 104514

You're very close. Assuming that regionStartPoint stores the row and column of the top left corner of where you want to start and it is a two-element array, and assuming that size_W contain the height and width of the region you want, also as a two-element array, simply do:

region_R = image_I(regionStartPoint(1):regionStartPoint(1)+size_W(1)-1,...
                   regionStartPoint(2):regionStartPoint(2)+size_W(2)-1,:);

In the above code, we want to access a range of row elements, where it starts from the top-left corner (regionStartPoint(1)), and we want to access elements that are size_W(1) = height elements, you access up to regionStartPoint(1)+size_W(1)-1. The reason why you subtract 1 is because when we index into a particular dimension, we are accessing every element that is within the range (inclusive). For example, if our starting row location was 1, and we had a height of 2, then we would only access rows 1 and 2. If we went from 1 and went up by height=2 elements, we would actually grab one extra element, so we'd get rows 1, 2 and 3. We don't want this last row, and so the subtraction of 1 helps us do this. In a similar fashion, if we wish to access a range of column elements, where it also starts from the top-left corner (regionStartPoint(2)), and we want to access elements that are size_W(2) = width elements, you access up to regionStartPoint(2)+size_W(2)-1 elements.

As such, we access matrices such that the first parameter specifies a range of rows you want, and the second parameter specifies a range of columns that you want. Because your image may be colour or grayscale, I used : as the last parameter so that you can obtain all of the 3D slices. If your image is grayscale, then this won't do anything, but if it's colour, it will give you a 3D matrix where each slice is of the size of the region you want extracted and there will be as many slices as there are colour planes.

Once you finish manipulating your image, you can put it back into image_I by:

image_I(regionStartPoint(1):regionStartPoint(1)+size_W(1)-1,...
               regionStartPoint(2):regionStartPoint(2)+size_W(2)-1,:) = region_R_final;

region_R_final would be the manipulated image after you extract it from image_I. This is exactly the same kind of syntax you saw before when you wanted to extract out a portion of the image, but now the roles are reversed. We wish to place this portion back into the image, and so you really just have to swap what's on the left and right side of the assignment (=) operator.


Alternatively, if you can't figure out the math to offset and extract out the stuff in the image, you can use imcrop from the Image Processing Toolbox. Specifically, you would do this:

region_r = imcrop(image_I, [regionStartPoint(2) regionStartPoint(1) size_W(2) size_W(1)]);

The first input is the image you want cropped, while the second element is an array of 4 elements that follows this format:

[x y w h]

x and y are the column and row locations of the top-left corner of where you want to extract, while w and h are the width and height of the portion you want to extract. If you have it flipped so that regionStartPoint has the column first followed by the row and sizeW has it such that the width comes first followed by the height, this code would simplify to:

region_r = imcrop(image_I, [regionStartPoint size_W]);

Just make sure you have the [x y w h] array in the correct order before running imcrop.


Minor Note

I'm not sure how you're extracting the MSB of each pixel in the image, but consider using bitget. This takes in a matrix or vector, and you specify which bit position you want to get. This will return an array of 0s/1s which is the same size as the input you provided and each position will give you what the corresponding bit was for each number in your matrix. In your case, you would do:

bitMSB = bitget(A, 8);

A would be the image you want to analyze and 8 is the 8th position / bit you want to get. We actually start counting from 1 instead of 0 in MATLAB (i.e. 1-indexing).


Good luck!

Upvotes: 4

Related Questions