Creating table of regionprops for each frame of a video
7 views (last 30 days)
Show older comments
I am working on a short video file with 240 frames in total. I needed to create a table with 3 columns ``NumberRegions``, ``MeanRegionSize`` and ``TotalRegionSize`` for each frame of the video. However, when I am trying to do it with ``regionprops`` inside a for loop with below given code, I am getting 1352x2 table, whereas I would like to get a table of 240x2 with the given code. Could you please help me with this? Many thanks!
v = VideoReader("denoised_gs_video.mp4");
firstFrame = im2double(read(v,1));
for idx = 1:v.NumFrames
frame = read(v,idx);
frame = im2double(frame);
frameDifference = abs(firstFrame - frame);
%applying segmentation function - returns segmented image
BW = carjoin1(frameDifference);
%getting properties
region{idx} = regionprops("table",BW,"Area","EulerNumber");
end
all_regions = vertcat(region{:});
0 Comments
Answers (1)
Walter Roberson
on 5 Jan 2023
Your use of variable name BW suggests that the output from carjoin1() is a binary image ("Black and White"). But possibly it as a label image, in which each different integer represents a different region.
When you pass a binary image to regionprops() then regionprops() will first run a labeling operation, finding connected regions. The default connectivity is 8 for 2D arrays, and 27 for 3D arrays. We cannot tell from the code whether BW is 2D or 3D -- partly because we do not know whether the inputs are RGB or grayscale, but also because we just do not know what carjoin1() does.
Once regionprops has a labeled array (either self-generated if a binary image was input, or if that is what you passed in) then regionprops will proceed to create output in which there is one entry for each different label index. Normally that would be by way of a nonscalar struct array, but you specified "table" so you are going to get a table with one row per label.
You generate NumFrames = 240 of those tables stored in a cell array. Then you vertcat() all of the tables together.
The resulting table would have 240 rows only if exactly one region is found per frame. As outside observers who do not know what carjoin1() does, we would assume that the reason you are getting a 1352 row table is that you are averaging 5 to 6 regions per frame.
Perhaps you should be doing something like bwareafilt() on BW . Or if BW is a binary image and you want all true pixels per frame to be treated as part of the same object, then instead of passing in BW to regionprops, pass in double(BW) so that it gets treated as a label image instead of a binary image.
2 Comments
Walter Roberson
on 7 Jan 2023
X = im2gray(X);
% Threshold image - manual threshold
BW = im2gray(X) > 1.700000e-01;
The second call to im2gray() is redundant; you already converted on the line above.
You are creating a logical array there, and the steps such as the erosion that you do all produce logical arrays. So the output of carjoin1() is a logical array. You did not do any steps to deliberately reduce the number of objects in the image (other than possibly merging some that are closed together.) [Note: with your octagon being radius 0, I think that step is not changing your BW.)
So your logical image is reaching regionprops. And as I indicated earlier when that happens, regionprops is going to do an internal labeling pass, dividing the logical image up into connected components. Unless you have strong reason to believe that due to characteristics of the image source, that there will only be exactly one connected region, then you should be expecting that regionprops is going to give statistics for multiple regions per file.
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!