Video Pixel Color Detection

3 ビュー (過去 30 日間)
Jack Gulling
Jack Gulling 2021 年 2 月 10 日
回答済み: Animesh 2024 年 4 月 8 日
I am trying to develop a script which will take a video, turn each frame into a jpg, then find the red values of each pixel in each frame. The goal is to see how variant the nonzero red values are and plot that variance vs time. Below is my code, looking for a way to clean up the rough data (even with a pure black screen still registers ~20% red pixels).
clear
clc
close all
workingDir = tempname;
mkdir(workingDir)
mkdir(workingDir,'images')
vid = VideoReader('testrun.mp4');
numFrames = vid.NumberOfFrames;
n=numFrames;
for i = 1:2:n
frames = read(vid,i);
imwrite(frames,['Image' int2str(i), '.jpg']);
im(i)=image(frames);
end
for i = 1:2:n
A=imread(['Image' int2str(i), '.jpg']);imshow(A)
[sz1 sz2 sz3]=size(A);
N=256;
%h0=figure(1);imshow(A);title('initial image');
ColorList={'Red' 'Green' 'Blue'};
gr=0:1/(N-1):1;
% checking how many different values pixels take in this picture P=unique(impixel(A,sz2,sz1))
% split RGB layers
A=A(:,:,1);
% filtering reds
cMap=zeros(N,3);cMap(:,1)=gr;
figure(2);hr=imshow(ind2rgb(A(:,:,1),cMap));title(ColorList{1});
R=hr.CData;
R1=R(:,:,1);
amount_red_pixels(i)=numel(find(R1>=0.35));
fprintf('\n amount red pixels: %s \n', num2str(amount_red_pixels(end)));
% sz1*sz2 % total amount of pixels in initial image
pc_red_pixels(i)=round(100*numel(find(R1>=0.35))/(sz1*sz2),3); % percentage of red pixels
fprintf('\n percentage red pixels: %s %%\n', num2str(pc_red_pixels(end)));
end
amount_red_pixels(amount_red_pixels == 0) = NaN;
pc_red_pixels(pc_red_pixels == 0) = NaN;
amount_red_pixels(isnan(amount_red_pixels)) = [];
pc_red_pixels(isnan(pc_red_pixels)) = [];
x = 2*[1:length(pc_red_pixels)];
plot(x,pc_red_pixels)
xlabel('Frames')
ylabel('Percentage of Red Pixels')

回答 (1 件)

Animesh
Animesh 2024 年 4 月 8 日
Hi Jack,
I understand you are finding that even a pure black screen registers approximately 20% red pixels, and you want to eliminate this behavior. This might be due to the way you’re defining and detecting “red” pixels. In your code, you’re considering any pixel with a red value greater than or equal to 0.35 as a “red” pixel. This threshold might be too low, especially considering that color values in an image can range from 0 to 1. Even a grayscale image will have some red value in it, because grayscale consists of equal amounts of red, green, and blue.
To address this, you could increase your threshold for what you consider to be a “red” pixel. Alternatively, you could change your approach to look for pixels where the red value is significantly higher than both the green and blue values, rather than just looking at the red value in isolation.
Here’s a modified version of your code that implements the latter approach:
for i = 1:2:n
A=imread(['Image' int2str(i), '.jpg']);
[sz1 sz2 sz3]=size(A);
N=256;
% split RGB layers
R=A(:,:,1);
G=A(:,:,2);
B=A(:,:,3);
% filtering reds
red_pixels = (R > G*1.2) & (R > B*1.2);
amount_red_pixels(i)=numel(find(red_pixels));
fprintf('\n amount red pixels: %s \n', num2str(amount_red_pixels(end)));
% sz1*sz2 % total amount of pixels in initial image
pc_red_pixels(i)=round(100*numel(find(red_pixels))/(sz1*sz2),3); % percentage of red pixels
fprintf('\n percentage red pixels: %s %%\n', num2str(pc_red_pixels(end)));
end
In this version, a pixel is considered “red” if its red value is at least 20% greater than both its green and blue values. You can adjust the 1.2 multiplier as needed to fine-tune your definition of a “red” pixel.

Community Treasure Hunt

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

Start Hunting!

Translated by