Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

project[5]: Image Processing 256 shades of grey Due Nov 17th, 11:59:59pm You are

ID: 3762803 • Letter: P

Question

project[5]: Image Processing

256 shades of grey

Due Nov 17th, 11:59:59pm

You are to find the steganographic image

(http://en.wikipedia.org/wiki/Steganography) in the included set of

images. For example, the following steganographic image is hidden in

this image:

Here’s how we did it. We have two files:

1. the hidden image (right, black and white)

2. the mask image (left, color/grayscale)

More specifically, you need to:

1. Write a program to hide an image inside of another image

2. Write a program to unmask the hidden image from an encoded image

a. allocate memory for a properly­sized multi­dimensional array

b. for each pixel in the hidden image, encode that information

along with the mask image

c. display the new image and write it to a file

a. allocate memory for a properly­sized multi­dimensional array

b. for each pixel in the encoded image, pull out the black and white

information

c. display the hidden image

Your completing this assignment demonstrates that you understand

nested loops

functions

if-then and if-then-else statements

multi-dimensional arrays

Completing the assignment also demonstrates that you have familiarity with

implementing an algorithm

understanding the structure of images

0. Setting up

Run the command ‘git pull’ from your cs135-f15 directory to get the

new project5 folder into your cs135 repository. Ask a TA or Fellow if

you do not know how.

Note: if you are running this on your own machine, you will need

to install new packages using the following command line (you

won’t need to do this in the ECC):

> sudo apt-get install libopencv-core-dev libopencv-highgui-dev

libopencv-imgproc-dev

1. Provided code

The following functions are provided (you will have to #include

“image_to_array.h” to use them):

typedef struct imagedata {

int width;

int height;

unsigned char** data;

} ImageData;

/* image_to_array:

arguments:

function to take an image filename, load that image (using OpenCV), and then

turn those image data into a 2D array (row, column, channel).

const char* filename: the filename of the image file to be loaded

bool threshold: whether to threshold the image to black and white

returns:

struct ImageData: a struct containing the image data that was loaded,

ImageData image_to_array( const char* filename, bool threshold );

/* array_to_image:

function to take an ImageData struct, convert that image to an OpenCV

image, and then open a window to display that image.

arguments:

ImageData data: an array to turn into an openCV image (char**)

char* display_name: the name to give the window that is opened

returns:

IplImage*: the openCV image represented by the array

(NULL if no window is desired)

IplImage* array_to_image( ImageData data, const char* display_name );

Remember that in class (lecture[10][1]) we discussed that greyscale

images can be represented by a 2D array of pixels, where pixels were

an unsigned char, with black == 0 and white == 255, and greys from 1

to 254. So an grayscale image is, in fact, a 2D array (width,height).

Encoding Method:

The method for hiding data in an existing image is rather simple. A

standard grayscale image is made up of a 2-dimensional array of

pixels. Each pixel is just an 8-bit unsigned char (a number between 0

and 255). 8 bits is usually enough to encode most information for a

grayscale image. However, while your eye can probably tell the

difference between a pixel value of 5 and a pixel value of 200, you

probably will not notice a small difference (say the difference

between 200 and 201). We can take advantage of this to hide

information that a computer can detect but a person could not.

So, if we start with an 8-bit pixel, we can throw out the least

significant bit, the one that distinguishes the value of 200 from 201.

The binary value of 200 is: 11100010 and 201 is: 11100011.

If we just toss out whatever value is in that last bit, we can hide a

single bit for the hidden image (like 1 if the hidden pixel should be

white, and 0 if the hidden pixel should be black).

Storing Images:

The ImageData struct is meant to hold that information. It has 3

fields:

width: the width of the image (in pixels)

height: the height of the image (in pixels)

data: and unsigned char** (2D array) to hold the image data

For example, if we had an instance of ImageData, named ‘image’, we can

refer to the value of the pixel at (64,45) using the following:

image.data[45][64]

that is the 45th row, the 64th column.

Note: the data field of this struct is not allocated by default,

in fact all of these fields are empty. The image_to_array

function will fill in those values (and even allocate the memory

for you) when reading the image from a file. So, if you were to

create a new ImageData, using the following line of code:

ImageData image;

All of the fields are empty by default and there is no memory

allocated for the image.data field.

However, if you were to use the image_to_array function like so:

image = image_to_array( “<filename>”, 0 );

Whatever image was in the file <filename> would be copied into the

image struct and memory allocated. If you wanted to display that image

(or any other image, for that matter) you could use the following

array_to_image(image,”original image”);

and a window named “original image” will pop up with the contents of

the ImageData object ‘image’.

You can save an image to a file with the following code:

IplImage* res_img = array_to_image(<ImageData>,<window title>);

cvSaveImage( <filename>, res_img, 0 );

Important Note: you need to add the following line:

cvWaitKey(0); // Wait for a keystroke in the window

right before the ‘return 0;’ line in your main function. This will

hold the windows open until you click on one of the windows and press

a key.

2. What you need to do

If you type ‘make’ in the project5 directory, you’ll get output like

make: *** No rule to make target `solve_image.o', needed by

`solve_image’. Stop.

this means that you need to create a file ‘solve_image.c This is where

you should put the main function for the portion of the project to

find the hidden image. Similarly, you should create a file,

make_steg.c for the portion of the project that encodes the image.

Your goal (for the encode portion): to write a program that will:

1.prompt the user to enter two filenames of images (we have

provided example .ppm image files to be used)

2.copy those images to an array (the ImageData struct, see provided

code above)

3.create new ImageData object to hold changed image

4.allocate memory for the new image data

5.for each pixel in the image

a.drop the least significant bit from the mask image pixel

value

b.add a 1 to that pixel value if the corresponding hidden

pixel value should be white

c.add a 0 (or don’t) to that pixel value if the corresponding

hidden pixel value should be black

6.display the new image

Your goal (for the solve portion): to write a program that will:

7.take a command-line argument which is the filename of an image

(we have provided two ppm files (one grayscale, one black and

white) to test with)

8.copy that image to an array (the ImageData struct, see provided

code below)

9.create new ImageData object to hold changed image

10. allocate memory for the new image data

11. for each pixel in the image

a.if the last bit is zero

i.make the corresponding pixel in the new image black

b.if the last bit is one

i.make the corresponding pixel in the new image white

12. display the new image

If you recall from before, to do this you need to:

create new files named ‘solve_image.c’ and ‘make_steg.c’

put a ‘main’ functions in those files

it is in these files where you will put your code.

Explanation / Answer

Answer:

-----------

1.Create a folder in C drive. Give it a name, lets say Testfile. It’s location should be C:Testfile.

2. Now move all the files you want to hide inside this folder. Also move the image file in which you want to hide those files. Let’s say the files which I want to hide are FileA.txt and FileB.txt, and the image file is Image.jpg. We are taking .txt files as an example. You can take files of any format (.mp3, .doc, .divx, .flv etc.) and any number of files.

3. Select both the files you want to hide (FileA.txt and FileB.txt in this case), right click and select “Add to Archive”. Make sure that you’ve got a file compression tool like WinZip or ZipGenius, a cool free winzip alternative, installed.

4. Give it a name. I have given Compressed.rar. You can give it any name.