How to read 0's and 1's from an array of images (originally from a video) and store each value (one per image) in a vector?

2 views (last 30 days)
Hello,
I don't do much coding, but I need to measure frequency of falling droplets through a slo-mo video (240 fps) captured on an iPhone. I plan to zoom in to a specific region, and increase contrast, so that in the whole video you might see 80-90% of the image turning white (or lighted up) everytime a droplet falls, this being the 1's, and black everytime there are no droplets (0's). Ideally, I would have a single value per each frame (I could get this by manipulating the image to only have 0's and 1's and getting the average, or any other way). Then, I want to store these values in a vector format to postprocess.
I downloaded the Image Processing Toolbox, and I was looking into the following functions:
readFrame, Videoreader, imcontrast (to increase contrast).
How can I do this? Or are there any other ideas to measure object frquency from a video?
Many thanks in advance!

Answers (2)

Siraj
Siraj on 23 Feb 2024
Edited: Siraj on 23 Feb 2024
Hi!
It is my understanding that you're trying to analyse a video to count the frequency of falling droplets. You'll enhance the video contrast to clearly mark frames with droplets as '1' and frames without droplets as '0'. This way, each video frame will be assigned either a '0' or a '1'. You plan to store these binary values into a vector for subsequent processing.
I’m assuming that the number of droplets in each frame is not a concern; the focus is solely on whether droplets are present or not.
There are various algorithms that can be used to detect the presence of water droplets in a frame. Experimentation with these methods can help you find the one that works best for your specific case. A simple method to start with is Otsu's thresholding, which can be used to binarize the image. The assumption here is that if water droplets are present, they will cause most of the pixels to become '1' after thresholding, whereas if no droplets are present, most of the pixels will be '0'. By counting the number of '1's in a frame and setting a count threshold 'x', you can determine the presence of droplets. If the count of '1's is greater than the threshold 'x', we can assume droplets are present and assign a '1' to that frame. It's important to adjust this threshold 'x' to account for noise, which might cause some pixels to be '1' even in the absence of droplets.
Refer to the following code for better understanding:
% Read the video file
v = VideoReader("xylophone_video.mp4");
% Initialize a vector to store the binary values for droplet presence
dropletPresenceVector = [];
% Define a threshold for the number of '1's that indicate droplet presence
pixelCountThreshold = 50; % This value will need to be adjusted based on experimentation
% Process each frame
while hasFrame(v)
% Read the current frame
frame = readFrame(v);
% Convert the frame to grayscale
grayFrame = rgb2gray(frame);
% Increase contrast if necessary (optional)
contrastAdjustedFrame = imadjust(grayFrame);
% Use Otsu's method to determine the threshold
thresholdValue = graythresh(contrastAdjustedFrame);
% Apply the threshold to get a binary image
binaryImage = imbinarize(contrastAdjustedFrame, thresholdValue);
% Count the number of '1's in the binary image
onesCount = sum(binaryImage(:));
% Determine if droplets are present based on the onesCount threshold
dropletsPresent = onesCount > pixelCountThreshold;
% Append a 1 for droplets present, 0 otherwise
dropletPresenceVector = [dropletPresenceVector; dropletsPresent];
end
MATLAB provides the “graythresh” function which applies Otsu's method for image thresholding. You can refer to the following link for more details.
An example is provided at the following link that demonstrates counting objects in a video stream. You can refer to this example to see if a similar approach can be applied to your case.
Hope this helps.
  2 Comments
Squids12
Squids12 on 24 Feb 2024
Thank you so much for all this information! Imbinarize sounds like a useful function!!! Since you mention “the number of droplets in each frame is not a concern”, what if it was? As in, what if I want to detect also the number of droplets in a frame? (I expect maximum 3 per frame, but most frames to be 1.
Image Analyst
Image Analyst on 24 Feb 2024
imbinarize can be useful, sometimes. It depends on what your images look like. I'm not optimistic about this algorithm -- did you see my Answer? Sounds like not.
Please attach the video, or a few frames that have one or more droplets in them and some frames that don't have droplets in them.
If you have any more questions, then attach your images or video with the paperclip icon after you read this:

Sign in to comment.


Image Analyst
Image Analyst on 23 Feb 2024
I don't think your algorithm is good. Contrast enhancement is not necessary and may even give deceptive results. Nor is Otsu thresholding a robust method. Why not? Because it will force a threshold regardless of whether there are droplets in the frame or not, so you will always have some "droplets" detected even if there are not any. It's best for situations where you have a bimodal histogram, but in the case of "no droplets present" you don't have that and it will be forced to split the unimodal histogram somewhere. So it's not good to use Otsu unless all your frame are guaranteed to have droplets in them. In my 40+-year experience it's almost always better to use a fixed threshold, not an automatically adjusting threshold. This will give you the correct answer regardless if there are no droplets, 100% droplets, or anywhere in between.
So assuming you have good control over your image capture conditions like exposure, lighting, zoom/magnification, etc. you can take the mean of the frame. You will probably find that if there are drops in the frame, the mean will be different than for no droplets. I'm attaching a demo that takes the mean of the frames and then put the means into an array. You can threshold that array if you want to give a binary judgment of whether there are droplets present or not.
  1 Comment
Squids12
Squids12 on 24 Feb 2024
Hello Image Analyst! Thank you so much! Actually, right after I posted this, I found another comment of yours with the rhinos video, and I was using that demo “ExtractMovieFrames.m” and I tweaked it so that I gather the 1’s and 0’s from the Binary Image plot. How does that compare to the demo you attach here, is this one better? Is the problem of “detecting droplets where there are none” present in that previous demo? I can share further details/the edited demo if needed. By the way, I must say that original demo (and I assume this one as well) is pretty awesome!

Sign in to comment.

Products


Release

R2022b

Community Treasure Hunt

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

Start Hunting!