Detecting specific color in video

Hi first of all I am very new to image/video processing so most of my work is modifiying others codes. After modifiying some of codes I manage to come up with this code:
%%Init
%Tresh
levelr = 0.26;
[vidDevice,vidInfo,hVideoIn] =Init;
while(1)
rgbFrame = step(vidDevice); % Acquire single frame
rgbFrame = flip(rgbFrame,2); % obtain the mirror image for displaying
rmat=rgbFrame(:,:,1);
gmat=rgbFrame(:,:,2);
bmat=rgbFrame(:,:,3);
diffFrameRed = im2bw(imsubtract(rmat,rgb2gray(rgbFrame)), levelr);
diffFrameGreen = im2bw(imsubtract(gmat,rgb2gray(rgbFrame)), 0);
diffFrameBlue = im2bw(imsubtract(bmat,rgb2gray(rgbFrame)), 0);
SummFrame = (diffFrameRed&diffFrameGreen&diffFrameBlue);
SummFrame = medfilt2(SummFrame, [3 3]); % Filter out the noise by using median filter
SummFrame = imfill(SummFrame,'holes');
se = strel('disk',1);
rgbFrame = imopen(SummFrame,se);
step(hVideoIn, rgbFrame); % Output video stream
end
Basically I tried for take frames from video then get the each color lair (R,G,B) substract it with rgb2gray then treshold it color value depending on color intensity that I want .finally I used and operator to sum all the lairs together go get the specific value of color. However it doesnt seem to work since it gives only black input at player

4 Comments

Ok, you've given us code that does not produce the right result. Problem is you haven't told us what the right result should be or explained the algorithm you're using.
In particular, I don't understand why you subtract the luminance (rgb2gray) from each colour channel. Note that rgb2gray is simply 0.2989 * rmat + 0.587 * gmat + 0.114 * bmat, so you have in effect:
diffFrameRed = im2bw(0.7011 * rmat - 0.587 * gmat - 0.114 * bmat, levelr)
diffFrameGreen = im2bw(-0.2989 * rmat + 0.413 * gmat - 0.114 * bmat, 0)
diffFrameBlue = im2bw(-0.2989 * rmat - 0.587 * gmat + 0.886 * bmat, 0)
And then I certainly don't understand why you multiply (the actual effect of & in your case) all these binary images. SummFrame will only be 1 where all three diff* are 1.
In fact, the following will create an image with all the possible colours (at 8-bit per channel):
[r, g, b] = ndgrid(0:255);
rgbFrame = im2double(uint8(reshape(cat(4, r, g, b), 4096, 4096, 3)));
If you apply your algorithm to that image
rmat=rgbFrame(:,:,1);
gmat=rgbFrame(:,:,2);
bmat=rgbFrame(:,:,3);
diffFrameRed = im2bw(imsubtract(rmat,rgb2gray(rgbFrame)), levelr);
diffFrameGreen = im2bw(imsubtract(gmat,rgb2gray(rgbFrame)), 0);
diffFrameBlue = im2bw(imsubtract(bmat,rgb2gray(rgbFrame)), 0);
SummFrame = (diffFrameRed&diffFrameGreen&diffFrameBlue);
You'll find that there isn't a single pixel of SummFrame that is on:
>> find(SummFrame)
ans =
0×1 empty double column vector
So your code is guaranteed to create a black image for all possible colours.
In order to detect color red I used these two lines;
if true
rmat=rgbFrame(:,:,1);
diffFrameRed = im2bw(imsubtract(rmat,rgb2gray(rgbFrame)), levelr);
end
Then applied the rest of the code. Then I thought that if I use these two lines for green and blue maybe I will get the desired colors depending on threshold levels. All of my codes are from youtube videos or some other resource as I said above I am new to this kind of stuff. In every source people detect red, green, blue but nobody explains how color orange or purple can be detected. I am trying to figure it out how to detect specific colors. Also thanks for your reply
rgb2gray is the luminance of your image. You're subtracting that from the red channel. I don't see how that helps in detecting any colour.
I would recommend grabbing a book on image processing. It will be a lot more reliable than youtube videos.
Detecting red, green or blue from an RGB image is easy, since these colours are already separated. To detect other colours you may be better off switching to a different colour space such as HSV or Lab.
Or as per Image Analyst's answer, experiment with the colour thresholder app and let it generate useful code.

Sign in to comment.

Answers (1)

Image Analyst
Image Analyst on 10 Jan 2018
There is a lot wrong with that code, which Guillaume pointed out. How about this: use the color thresholder (on the Apps tab) to build a classifier for the color you want. You then pass your RGB image into that and set out a mask of where that color is. It can handle purplse, orange, etc. Then, I'm a little unclear on what you want to do with the mask. ANDing, median filtering, and opening - what's that supposed to accomplish? What do you want as a final output? A masked RGB video (blackened outside the color)? A video of just the binary masks? A video with the color regions outlines over the video in red or some outline color? I have no idea.

Asked:

on 9 Jan 2018

Commented:

on 10 Jan 2018

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!