how to calculate height of a crop (like wheat,rice etc)? if i have a side view of the crops
2 次查看(过去 30 天)
显示 更早的评论
please help me with an algorithm to calculate height from the ground
0 个评论
采纳的回答
Image Analyst
2017-2-19
I'd probably start by looking at the hue channel and segmenting out green. Then I'd project horizontally and look for the half way point. Here's a start:
hsvImage = rgb2hsv(rgbImage);
hImage = hsvImage(:,:,1);
binaryImage = hImage > lowThreshold & himage < highThreshold
Use the Color thresholder app on the Apps tab to determine that the thresholds should be.
Then
verticalProfile = sum(binaryImage, 2);
halfWay = (max(verticalProfile) + min(verticalProfile) / 2;
index = find(verticalProfile > halfWay, 1, 'first');
and so on. See my attached spatial calibration demo to convert pixels into meters.
See my File Exchange for color segmentation demos: http://www.mathworks.com/matlabcentral/fileexchange/?term=authorid%3A31862
更多回答(2 个)
Image Analyst
2017-2-19
See this code:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 15;
%===============================================================================
% Get the name of the image the user wants to use.
baseFileName = 'maize4.jpg';
% Get the full filename, with path prepended.
folder = pwd
fullFileName = fullfile(folder, baseFileName);
%===============================================================================
% Read in a demo image.
originalRGBImage = imread(fullFileName);
% Get the dimensions of the image. numberOfColorChannels should be = 3.
[rows, columns, numberOfColorChannels] = size(originalRGBImage);
% Display the original color image.
subplot(2, 3, 1);
imshow(originalRGBImage, []);
axis on;
caption = sprintf('Original RGB Color Image, %s', baseFileName);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% Get rid of tool bar and pulldown menus that are along top of figure.
set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
drawnow;
hp = impixelinfo(); % Set up status line to see RGB values when you mouse over the image.
grayImage = rgb2gray(originalRGBImage); % Used for stdfilt
% grayImage = originalRGBImage(:,:,3);
% Display the image.
subplot(2, 3, 2);
imshow(grayImage, []);
axis on;
caption = sprintf('Gray Scale Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
% Do an edge detection filter to find "complicated" areas, not sky.
edgeImage = edge(grayImage, 'Sobel', .01); % Whatever value works for you.
% Display the image.
subplot(2, 3, 3);
imshow(edgeImage, []);
axis on;
caption = sprintf('Edge Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
verticalProfile = sum(edgeImage, 2);
subplot(2, 3, 4);
plot(verticalProfile, 'b-');
halfWay = (max(verticalProfile) + min(verticalProfile)) / 2
topRow = find(verticalProfile > halfWay, 1, 'first')
y = verticalProfile(topRow);
grid on;
xlabel('Rows', 'FontSize', fontSize, 'Interpreter', 'None');
ylabel('Edge Signal', 'FontSize', fontSize, 'Interpreter', 'None');
title('Vertical Profile of Edge Image', 'FontSize', fontSize, 'Interpreter', 'None');
xlim([1, rows]);
hold on;
line([1, topRow], [y, y], 'Color', 'r', 'LineWidth', 2); % Horizontal line
line([topRow, topRow], [0, y], 'Color', 'r', 'LineWidth', 2); % Vertical line
% Display the original color image.
subplot(2, 3, 5);
imshow(originalRGBImage, []);
axis on;
caption = sprintf('Original Image with Crop Top and Bottom Indicated');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
% Draw lines along the top of the crop.
hold on;
line([1, columns], [topRow, topRow], 'Color', 'r', 'LineWidth', 3);
% Draw lines along the base of the crop.
% Let's just assume we know in advance that it's at row 220.
bottomRow = 270;
line([1, columns], [bottomRow, bottomRow], 'Color', 'r', 'LineWidth', 3);
% Compute height.
heightInRows = abs(bottomRow - topRow);
spatialCalibrationFactor = 0.01; % Meters per pixel.
heightInMeters = spatialCalibrationFactor * heightInRows;
message = sprintf('The crop height = %f meters', heightInMeters);
fprintf('%s\n', message);
uiwait(helpdlg(message));
2 个评论
Image Analyst
2017-2-20
You can determine the spatial calibration factor by measuring a known distance, like in the demo I attached in my other answer.
The sensitivity is controlled by
halfWay = (max(verticalProfile) + min(verticalProfile)) / 2
You can change it to
halfWay = sensitivityFactor * (max(verticalProfile) - min(verticalProfile)) + min(verticalProfile);
where sensitivityFactor is a value between 0 and 1.
This will not affect the Sobel edge detection, which is done before the thresholding. Basically we're depending on the fact that the sky will be smooth and the crops will be complicated. If you have complex clouds in the sky, then you may need to make modifications.
Walter Roberson
2017-2-19
I see that the image is marked as being from 2012:07:06 11:27:40 . Can that information be relied upon? What is known about the latitude and longitude? With sufficient information about the time and position, the position of the Sun in the sky could be determined, and that together with the length of the shadows would tell you how tall the objects were.
If, that is, you could manage to extract shadows. The pixelation on the image is awful. The original image was roughly 6000 x 4000 but it has been scaled down to only 419 wide.
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Convert Image Type 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!