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

采纳的回答

Image Analyst
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
  1 个评论
Sharad C
Sharad C 2017-2-19
really sorry Image Analyst, It's a fine answer but it'd be helpful if you could elaborate on: " I'd project horizontally and look for the half way point "

请先登录,再进行评论。

更多回答(2 个)

Image Analyst
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 个评论
Sharad C
Sharad C 2017-2-20
Thank you very much Image Analyst. The code above is quite eloquent.
I have three small queries, as follows:
  • The metre per pixel value could be calculated using the method you stated in the attachment, am I right?
  • The thresholding value or sensitivity of the edge detection part depends on what parameter?
  • How does the 'sobel' method change with increase or decrease in sensitivity?
Thanks again.
Image Analyst
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
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.

类别

Help CenterFile Exchange 中查找有关 Convert Image Type 的更多信息

标签

Community Treasure Hunt

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

Start Hunting!

Translated by