I am not getting exactly gray image on converting video to grayscale? - matlab

This is my code. The output is not exactly gray. Can someone tell me what is the problem in the code ?
obj = VideoReader('shaky_cars.avi');
height = obj.Height;
width = obj.Width;
factor = 200/height;
num=10;
intendedFrame = 20;
video = read(obj , [intendedFrame , intendedFrame+num]);
for i = 1:1+num
grayVideo(:,:,i) = double(imresize((rgb2gray(video(:,:,:,i))) , factor));
end
[height , width] = size(grayVideo(:,:,1));
figure(1);imagesc(grayVideo(:,:,1));
And this is the output

A few questions: Have you printed out the images before and after to see what's happening at each step?
Why are you converting the frames to type double?
Suggestion: Try converting the image to uint8 by doing uint8(grayVideo(:,:,i)) and use a gray colormap colormap(gray(256)).
Let me know if this helps

Instead of using imagesc, you can use
imshow(uint8(grayVideo(:,:,1)))
to display your grayscale images.

Related

Dynamically setting a 'targetSize' for centerCropWindow2d()

Following the example from the documentation page of the centerCropWindow2d function, I am trying to dynamically crop an image based on a 'scale' value that is set by the user. In the end, this code would be used in a loop that would scale an image at different increments, and compare the landmarks between them using feature detection and extraction methods.
I wrote some test code to try and isolate 1 instance of this user-specified image cropping,
file = 'frameCropped000001.png';
image = imread(file);
scale = 1.5;
scaled_width = scale * 900;
scaled_height = scale * 635;
target_size = [scaled_width scaled_height];
scale_window = centerCropWindow2d(size(image), target_size);
image2 = imcrop(image, scale_window);
figure;
imshow(image);
figure;
imshow(image2);
but I am met with this error:
Error using centerCropWindow2d (line 30)
Expected input to be integer-valued.
Error in testRIA (line 20)
scale_window = centerCropWindow2d(size(image), target_size);
Is there no way to do use this function the way I explained above? If not, what's the easiest way to "scale" an image without just resizing it [that is, if I scale it by 0.5, the image stays the same size but is zoomed in by 2x].
Thank you in advance.
I didn't take into account that the height and width for some scales would NOT be whole integers. Since Matlab cannot crop images that are inbetween whole pixel numbers, the "Expected input to be integer-valued." popped up.
I solved my issue by using Math.floor() on the 'scaled_width' and 'scaled_height' variables.

Matlab - Removing image background using normalization

I have an image like this:
my goal is to get the output under background normalization at this link.
Following the above link, I did the following:
(1). I first dilate the image to get the background
(2). then try to remove it via normalization
I got the background:
However, when I try to do the normalized division, I get this :
(black borders added to make clear of the boundary of the image)
this is my code:
image = imread('image.png');
image = rgb2gray(image);
se = offsetstrel('ball',9,9);
dilatedI = imdilate(image,se);
output = imdivide(image,dilatedI);
imshow(output,[]);
using
imshow(output)
just gives a black image.
I thought it might be a type conversion issue, but based on the resources mentioned earlier, I am uncertain if it is the case...
Any advice would be appreciated
Just make sure you dont do integer division! your images are integer type, so 4/5 returns 0 and 5/4 returns 1, not a floating point number. Just convert to float before dividing:
image = imread('https://i.stack.imgur.com/bIVRT.png');
%image = rgb2gray(image); The image is not a RGB online
se = offsetstrel('ball',21,21);
dilatedI = imdilate(image,se);
output = imdivide(double(image),double(dilatedI));
figure
subplot(121)
imshow(image);
subplot(122)
imshow(output);

I want to save the detected face as a jpg image in matalb

I have detected the face from an image. Now I want to store that detected face as a jpg image in matlab. Plzz some one guide me.
code for face detection is:
img = imread('C:\Users\Anmol\Desktop\face_recognition\Pgm\image1');
facedetector = vision.CascadeObjectDetector()
BBOX = step(facedetector,img)
B = insertObjectAnnotation(img,'rectangle',BBOX,'Face');
title('detected faces');
n = size(BBOX,1);
string = num2str(n);
str = strcat('no of face=',string);
disp(str);
I would be very thankful is some could provide me the code for storing the detected face as a jpg image
You can crop the face using imcrop, and then save the cropped image using imwrite.
faceImage = imcrop(img, BBOX(1,:))
imwrite(img, 'face.jpg');

How do I convert the whole image to grayscale except for a sub image which should be in color?

I have an image and a subimage which is cropped out of the original image.
Here's the code I have written so far:
val1 = imread(img);
val2 = imread(img_w);
gray1 = rgb2gray(val1);%grayscaling both images
gray2 = rgb2gray(val2);
matchingval = normxcorr2(gray1,gray2);%normalized cross correlation
[max_c,imax]=max(abs(matchingval(:)));
After this I am stuck. I have no idea how to change the whole image grayscale except for the sub image which should be in color.
How do I do this?
Thank you.
If you know what the coordinates are for your image, you can always just use the rgb2gray on just the section of interest.
For instance, I tried this on an image just now:
im(500:1045,500:1200,1)=rgb2gray(im(500:1045,500:1200,1:3));
im(500:1045,500:1200,2)=rgb2gray(im(500:1045,500:1200,1:3));
im(500:1045,500:1200,3)=rgb2gray(im(500:1045,500:1200,1:3));
Where I took the rows (500 to 1045), columns (500 to 1200), and the rgb depth (1 to 3) of the image and applied the rgb2gray function to just that. I did it three times as the output of rgb2gray is a 2d matrix and a color image is a 3d matrix, so I needed to change it layer by layer.
This worked for me, making only part of the image gray but leaving the rest in color.
The issue you might have though is this, a color image is 3 dimensions while a gray scale need only be 2 dimensions. Combining them means that the gray scale must be in a 3d matrix.
Depending on what you want to do, this technique may or may not help.
Judging from your code, you are reading the image and the subimage in MATLAB. What you need to know are the coordinates of where you extracted the subimage. Once you do that, simply take your original colour image, convert that to grayscale, then duplicate this image in the third dimension three times. You need to do this so that you can place colour pixels in this image.
For RGB images, grayscale images have the RGB components to all be the same. Duplicating this image in the third dimension three times creates the RGB version of the grayscale image. Once you do that, simply use the row and column coordinates of where you extracted the subimage and place that into the equivalent RGB grayscale image.
As such, given your colour image that is stored in img and your subimage stored in imgsub, and specifying the rows and columns of where you extracted the subimage in row1,col1 and row2,col2 - with row1,col1 being the top left corner of the subimage and row2,col2 is the bottom right corner, do this:
img_gray = rgb2gray(img);
img_gray = cat(3, img_gray, img_gray, img_gray);
img_gray(row1:row2, col1:col2,:) = imgsub;
To demonstrate this, let's try this with an image in MATLAB. We'll use the onion.png image that's part of the image processing toolbox in MATLAB. Therefore:
img = imread('onion.png');
Let's also define our row1,col1,row2,col2:
row1 = 50;
row2 = 90;
col1 = 80;
col2 = 150;
Let's get the subimage:
imgsub = img(row1:row2,col1:col2,:);
Running the above code, this is the image we get:
I took the same example as rayryeng's answer and tried to solve by HSV conversion.
The basic idea is to set the second layer i.e saturation layer to 0 (so that they are grayscale). then rewrite the layer with the original saturation layer only for the sub image area, so that, they alone have the saturation values.
Code:
img = imread('onion.png');
img = rgb2hsv(img);
sPlane = zeros(size(img(:,:,1)));
sPlane(50:90,80:150) = img(50:90,80:150,2);
img(:,:,2) = sPlane;
img = hsv2rgb(img);
imshow(img);
Output: (Same as rayryeng's output)
Related Answer with more details here

selecting particular region of image for filtering

Am trying to extract the red portion of image as shown in the link image
http://tinypic.com/r/2qntaip/7
I worked out like this
RGB = imread('Frame 0233.jpeg');
RGB =im2double(RGB );
img = rgb2gray(RGB);
n=[2 -1 -1;-1 2 -1;-1 -1 2];%detecting -45 degree lines in image
pout_adapthisteq = adapthisteq(img);
a3 = imfilter(pout_adapthisteq,n);
figure(1),imshow(a3);
Got the result image like this http://tinypic.com/view.php?pic=ad1zn&s=7
Can anyone help me to extract the line only in the red portion
This is how I would do it in Mathematica: