This week I tried out the following two activities. I implemented the first two as Android apps, so I will be attaching the code and also the apk, so that you can run it on your devices if you like. The last one is in Matlab
Activity 1: Gamma Correction in Images
So we know gamma correction is a point operation that transforms the image by raising it to an exponent (gamma). Given an image in the range 0 to 255, I first converted it into the range 0 to 1, then performed the exponentiation and finally transferred back to 0-255 range. Notice this experiment is done with a grayscale image.
The app displays the camera captured image on the screen initially. There is a textbox which you can use to enter desired gamma values. Depending on the gamma value entered, the screen will now display the processed image. You can try the Gamma.apk to see it in action.
The relevant code uses OpenCV (C++). It is called by the Java based UI code through the JNI.
JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial2_Tutorial2Activity_FindFeatures(JNIEnv*, jobject, jlong addrGray, jdouble gamma)
{
Mat& mGr = *(Mat*)addrGray; //get the reference to the Mat file that represents the (grayscale) image
mGr.convertTo(mGr, CV_32F, 1.0/255.0); //Convert the integer valued image to float valued image (CV_32F)... also scale down by 255 so that we are in the 0 to 1 range
cv::pow(mGr, gamma, mGr); //Raise the image to power gamma are store it in the same Mat variable
mGr.convertTo(mGr, CV_8U, 255); //Convert back to integer image and also scale up by 255 so that we land in the 0-255 range
}
Gamma = 1
Gamma = 0.3
Gamma = 2.5
Background: I am currently working on an app that requires some face detection. For that we need to normalize the illumination intensity of the face. I am using this technique (section 5) for illumination normalization. The first step involves gamma correction. Nice to find it's use in my work.
Activity 2: Blending Colours
In this activity, I made an app that displays some coloured tiles. A slider can be slid and the colours of the tiles change depending on the slider position.
There are 2 pairs of tiles. Consider a single pair of tiles. Initially one of them has colour C1(R1, B1, G1) and the other has colour C2(R2, B2, G2). The values in the brackets denote the RGB compositions of the colours C1 and C2. When the slider is slid to max position C1 changes to C2 and vice versa. In intermediate positions the tiles display a blended colour.
How are the colours blended? Consider that the slider is in position p and it can slide between 0 to 100. We want colour C1 and C2 to blend according to the proportion p/100. Therefore the intermediate colour is p*C1 + (1-p)*C2. Notice colours C1 and C2 are actually made of RGB components so the actual equations would be p*R1 + (1-p)*R2 (and so on for G and B too)
Also in computer colours are usually not denoted by 3 separate numbers. Instead they are combined into a single integer. Also there is an alpha channel present if RGBA format is used. Alpha channel denotes transparency. Therefore colour is represented in a single integer as follows: A(MSB 8 bits, 31 to 24), R (23 to 16), G (15 to 8) and B (LSB 8 bits, 7 to 0)
Image showing bit allocation for RGBA colour system
Below is the function to blend two colours according to a given ratio
int blend (int a, int b, float p) {
int aA = a >>> 24; //shift by 24 bits to get A values into LSB
int aR = ((a & 0xff0000) >>> 16); //Mask other bits and shift by 16 bits to get R values into LSB
int aG = ((a & 0xff00) >>> 8); //Mask other bits and shift by 8 bits to get R values into LSB
int aB = (a & 0xff); //Mask bits 31 to 8
int bA = b >>> 24;
int bR = ((b & 0xff0000) >>> 16);
int bG = ((b & 0xff00) >>> 8);
int bB = (b & 0xff);
int A = ((int)(aA * (1.0f - p)) + (int)(bA * p)); //combine each channel separately using appropriate ratios
int R = ((int)(aR * (1.0f - p)) + (int)(bR * p));
int G = ((int)(aG * (1.0f - p)) + (int)(bG * p));
int B = ((int)(aB * (1.0f - p)) + (int)(bB * p));
return A << 24 | R << 16 | G << 8 | B; //recombine channels
}
A video demonstrating the app is attached below.
Background: I built this app just a few days ago as the final project of UMD's course on Android App development on Courseera.
Activity 3: PSNR metric's behaviour on rotation
The PSNR between two images is usually calculated as (1/MN)*sum( (A(x,y) - D(x,y))2), where MN is product of number of rows and columns, D is the reference image and A is the actual image. This metric is useful in comparing how similar two images are. But PSNR suffers from a few problems. For example it performs very badly when comparing two shifted or rotated images. Here we study the effect of rotation on PSNR.
The following image is used:
PSNR values vs rotation (in degree)
I
In the above image we see the PSNR values plottedfor different rotations. As expected the PSNR is 0 for rotations 0o and 360o. For 180o the PSNR is quite low, which is obvious as the image is a set of vertical stripes which look the same as the original on half a rotation. But other than these values PSNR remains quite high. It oscillates quite a bit in till it reaches 30o, after which it remains almost constant till it drops down at 180o. The graph is symmetric about 180 degree.
PSNR vs Degree of rotation for different spatial frequencies
Next I varied the spatial frequency of the vertical stripes image that I used as my test image and plotted the PSNRs for different rotation angles from 0 to 30o. The lighter gray plots have smaller spatial frequency and the darker gray plots are higher spatial frequency images. As spatial frequency increases the rate of increase of PSNR error increases (for small rotations). For larger angles of rotations though, the PSNR error settle down to almost the same value for all spatial frequencies.
The MATLAB code for the above experiments are attached below.
Footnote on installing the apps
To install the android apps you can copy the apk to your phone/tablet. Then open a browser on your phone (eg: ES File Explorer) and go to the location of the apk and click on it to install.It may ask you for certain permissions. For details please check this site.
Also when you run the gamma app, it will probably say you don't have OpenCV installed. So you have to install OpenCV Manager for it to work. The colour blending app should work just like that. It does not require OpenCV.