Multiple image thresholding and measure distance

3 views (last 30 days)
Hi, I am measuring flame heights from images, extracted from vdo clip. I can do threshold to remove background and set a scale virtually to measure flame height. But is there any code or way to measure multiple images thresholding and heights? i need this help very much. I have 6000 images in one vdo. It will take long doing one by one. Height of the frame is 120 cm, all images are cropped in one size. Can i get the height somehow mesuring the pixel value?

Answers (2)

DGM
DGM on 16 Nov 2023
Edited: DGM on 16 Nov 2023
Nothing is going to be able to automatically read the background scale from an image like that. It's also not exactly square or flat. If the images are consistently fixed with respect to the background scale, you can just create some sort of calibration information one way or another. If the images move with respect to the background scale, then all bets are off.
I just manually guessed where the scale lines were and created an annotated copy of the image to use as a reference.
% GET THE REFERENCE GRID %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% the annotated image
annotated = imread('TA.png');
% create and filter mask to find grid lines
lmk = annotated(:,:,1) < 5;
lmk = bwareafilt(lmk,12);
lmk = bwskel(lmk);
% sample lines near L and R image edges
% length of cm0 and y0 vectors should match
ycm0 = 120:-10:10;
x0 = [5 size(lmk,2)-5];
yL0 = find(lmk(:,x0(1)));
yR0 = find(lmk(:,x0(2)));
% PROCESS A TEST IMAGE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% the test image
inpict = imread('Top.png');
inpict = im2gray(inpict);
% do some sort of binarization
mask = imbinarize(inpict);
imshow(mask,'border','tight')
% find the column and row of the leftmost pixel of the top row
[x,y] = find(mask.',1);
% use the annotations to find the position using quasi-2D interpolation
% this is a quick and adequate way to deal with sparse half-gridded samples
% where extrapolation is (probably) needed
ycmL = interp1(yL0,ycm0.',y,'linear','extrap');
ycmR = interp1(yR0,ycm0.',y,'linear','extrap');
ycm = interp1(x0,[ycmL ycmR],x,'linear','extrap')
ycm = 118.7162

Image Analyst
Image Analyst on 16 Nov 2023
See attached demos where I read frames from a video and then process them. You could make the obvious adaptations, such as the name(s) of the video, replacing taking the mean by thresholding like @DGM (or it might be better to use a fixed threshold), etc.
  4 Comments
MD FAISAL RASHID
MD FAISAL RASHID on 19 Nov 2023
% Can you check? I want to get pixels up to 128. I replaced the codes but it found errors. I think I don't need all these codes for my issue.
% Demo to extract frames and get frame RGB means from a movie.
% Illustrates the use of the VideoReader and VideoWriter classes.
% A Mathworks demo (different than mine) is located here http://www.mathworks.com/help/matlab/examples/convert-between-image-sequences-and-video.html
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures.
clear; % Erase all existing variables.
workspace; % Make sure the workspace panel is showing.
fontSize = 22;
% Open the rhino.avi demo movie that ships with MATLAB.
% First get the folder that it lives in.
% folder = fileparts(which('rhinos.avi')); % Determine where demo folder is (works with all versions).
folder = fileparts(which('Exp11.mp4')); % Determine where demo folder is (works with all versions).
% Pick one of the two demo movies shipped with the Image Processing Toolbox.
% Comment out the other one.
% movieFullFileName = fullfile(folder, 'rhinos.avi');
movieFullFileName = fullfile(folder, 'Exp11.mp4');
% Check to see that it exists.
if ~exist(movieFullFileName, 'file')
strErrorMessage = sprintf('File not found:\n%s\nYou can choose a new one, or cancel', movieFullFileName);
response = questdlg(strErrorMessage, 'File not found', 'OK - choose a new movie.', 'Cancel', 'OK - choose a new movie.');
if strcmpi(response, 'OK - choose a new movie.')
[baseFileName, folderName, FilterIndex] = uigetfile('*.avi');
if ~isequal(baseFileName, 0)
movieFullFileName = fullfile(folderName, baseFileName);
else
return;
end
else
return;
end
end
try
videoObject = VideoReader(movieFullFileName);
% Determine how many frames there are.
numberOfFrames = videoObject.NumFrames;
vidHeight = videoObject.Height;
vidWidth = videoObject.Width;
numberOfFramesWritten = 0;
% Prepare a figure to show the images in the upper half of the screen.
figure;
% screenSize = get(0, 'ScreenSize');
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Loop through the movie, writing all frames out.
% Each frame will be in a separate file with unique name.
meanGrayLevels = zeros(numberOfFrames, 1);
meanRedLevels = zeros(numberOfFrames, 1);
meanGreenLevels = zeros(numberOfFrames, 1);
meanBlueLevels = zeros(numberOfFrames, 1);
for frame = 1 : numberOfFrames
% Extract the frame from the movie structure.
thisFrame = read(videoObject, frame);
% Display it
hImage = subplot(1, 2, 1);
image(thisFrame);
axis image;
caption = sprintf('Frame %4d of %d.', frame, numberOfFrames);
title(caption, 'FontSize', fontSize);
drawnow; % Force it to refresh the window.
% Calculate the mean gray level.
% grayImage = rgb2gray(thisFrame);
% meanGrayLevels(frame) = mean(grayImage(:));
mask = grayImage > TheThreshold;
mask = bwareaopen(mask, 50);
% Get rid of blobs smaller than 50 pixels which are probably noise.
% Find top row
[whiteRows, whitePixels] = find(mask);
% Get rows and columns of every white pixel.
topRow(frameNumber) = min(whiteRows)
% Find row closest to top of frame.
% Calculate the mean R, G, and B levels.
meanRedLevels(frame) = mean(mean(thisFrame(:, :, 1)));
meanGreenLevels(frame) = mean(mean(thisFrame(:, :, 2)));
meanBlueLevels(frame) = mean(mean(thisFrame(:, :, 3)));
% Plot the mean gray levels.
hPlot = subplot(1, 2, 2);
hold off;
plot(meanGrayLevels, 'k-', 'LineWidth', 3);
hold on;
plot(meanRedLevels, 'r-', 'LineWidth', 2);
plot(meanGreenLevels, 'g-', 'LineWidth', 2);
plot(meanBlueLevels, 'b-', 'LineWidth', 2);
grid on;
% Put title back because plot() erases the existing title.
title('Mean Gray Levels', 'FontSize', fontSize);
if frame == 1
xlabel('Frame Number');
ylabel('Gray Level');
% Get size data later for preallocation if we read
% the movie back in from disk.
[rows, columns, numberOfColorChannels] = size(thisFrame);
end
% Update user with the progress. Display in the command window.
progressIndication = sprintf('Processed frame %4d of %d.', frame, numberOfFrames);
disp(progressIndication);
% Increment frame count (should eventually = numberOfFrames
% unless an error happens).
numberOfFramesWritten = numberOfFramesWritten + 1;
end
% legend('Red', 'Green', 'Blue', 'Average');
% Alert user that we're done. finishedMessage = sprintf('Done! It processed %d frames of\n"%s"', numberOfFramesWritten, movieFullFileName);
finishedMessage = sprintf('Done! It processed %d frames of\n"%s"', numberOfFramesWritten, movieFullFileName);
disp(finishedMessage); % Write to command window.
uiwait(msgbox(finishedMessage)); % Also pop up a message box.
catch ME
% Some error happened if you get here.
strErrorMessage = sprintf('Error extracting movie frames from:\n\n%s\n\nError: %s\n\n)', movieFullFileName, ME.message);
uiwait(msgbox(strErrorMessage));
end
Image Analyst
Image Analyst on 19 Nov 2023
Edited: Image Analyst on 19 Nov 2023
Again, you probably don't need the stuff about computing and plotting the mean. And the index should be frame, not frameNumber in
topRow(frameNumber) = min(whiteRows)

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!