本文介紹了:插針式土壤粗糙度儀的數字化步驟,以及具體的Matlab實現代碼。這個小程序寫的挺有意思的,可以實現插針式土壤粗糙度儀的互動式數字化。
下圖是試驗中拍攝一張土壤廓線圖,有興趣的可以拿去練習下。
一、插針式土壤粗糙度儀的數字化步驟
1. 當前目錄設置為圖片的文件夾目錄,運行腳本。首先,在白板上輸入圖片名稱,如下圖所示,輸入名稱:FIELD-2-POINT-3-ALONG-W。然後,將OK轉到步驟2。
2. 輸入兩個點以獲得要放大的範圍。請注意,範圍中應包含四個紅點。
3. 輸入四個紅點的中心位置;請注意,輸入的點將標記為綠色,按「Enter」鍵將結束輸入。然後,程序將使用輸入的位置消除圖像變形。
4. 在重新投影的圖片上,再次輸入四個紅點的中心位置。請注意,輸入的點將標記為綠色,按「Enter」鍵將結束輸入。然後,程序將刪除由四個點定義的範圍之外的圖片邊框。
5. 逐個描畫插針的高度。請注意,輸入的點將標記為紅色,在完成所有點後,按「Enter」鍵結束輸入。然後,程序將以釐米為單位計算每個點的坐標。結果的X間距將插值為1 cm,然後繪製在新圖中。
6. 最後,可以對數字化後的結果進行核驗。在彈出的問題對話框中,您可以選擇「繼續」按鈕來數字化下一張圖片,或者按「結束任務」結束你的工作。
%% 1.獲取要數字化的圖片 clear, clc close all
% 圖片所在的文件夾 picturedir = Z:Works_UKPinboard_photos_20180824 oughness_extraction;
% 選擇要數字化的圖片 filename = uigetfile(*.JPG,Pick a file,picturedir); roughness_picture = importdata([picturedir filename]);
%% 2.獲取有效範圍 screensize = get(0,ScreenSize); % get screen resolution screensize2 = screensize; screensize2(1) = screensize(1)+screensize(3);
% 最大化圖片 figure(Name,filename,position,screensize) imagesc(roughness_picture);
% 輸入採樣點信息 pointName = cell2mat(inputdlg(Please input the point name:,Input,[1 50])); pointName = matlab.lang.makeValidName(pointName);
% 放大至有效作圖範圍 uiwait(msgbox(Please input two points, then enlarge to that extend));
p = ginput(2); % the corners of the polygon sp(1) = min(floor(p(1)), floor(p(2))); %xmin sp(2) = min(floor(p(3)), floor(p(4))); %ymin sp(3) = max(ceil(p(1)), ceil(p(2))); %xmax sp(4) = max(ceil(p(3)), ceil(p(4))); %ymax
% 顯示結果 MM = roughness_picture(sp(2):sp(4), sp(1): sp(3),:);
imagesc(MM);
%% 3.糾正圖片變形 uiwait(msgbox(Please input the central locations of the four red point to wrap the picture!)); % [x_pixs,y_pixs] = ginput; x_pix4 = []; y_pix4 = []; finish=false; set(gcf,CurrentCharacter,@);
while ~finish % get the coordinates of the four points % check for keys key = get(gcf,CurrentCharacter); children = get(gca, children);
if key~=@ % has it changed from the dummy character? set(gcf,CurrentCharacter,@); % reset the character
if strcmp (key, char(13)) % finish=true; break; % if input delete, then delete the current point elseif strcmp(key, char(127)) && length(children)>2
delete(children(1)); delete(children(2)); x_pix4 = x_pix4(1:end-2); y_pix4 = y_pix4(1:end-2); continue; end end
[x_pix1,y_pix1] = ginput(1); hold on plot(x_pix1,y_pix1,*g)
x_pix4 = [x_pix4 x_pix1]; y_pix4 = [y_pix4 y_pix1]; end hold off
% square sum of the coordinates, and sort the matrix corSUM = x_pix4.^2+y_pix4.^2; [corSUM_sort,I] = sort(corSUM);
% exchange (swap) the second and third elements I([2 3]) = I([3 2]);
% from left-right and up-down x_pix4 = x_pix4(I); y_pix4 = y_pix4(I);
topLeft = [x_pix4(1), y_pix4(1)]; topRight = [x_pix4(2), y_pix4(2)]; botRight = [x_pix4(4), y_pix4(4)]; botLeft = [x_pix4(3), y_pix4(3)];
U = [topLeft; topRight; botRight; botLeft]; width = size(MM,2); height = size(MM,1); topLeftNew = [1 1]; topRightNew = [width,1]; bottomLeftNew = [1,height]; bottomRightNew = [width,height]; X = double([topLeftNew; topRightNew; bottomRightNew; bottomLeftNew;]); tform = fitgeotrans(U, X, projective); MM_wrap = imwarp(MM, tform);
% 顯示糾偏後的結果 imagesc(MM_wrap)
%% 4.裁剪多餘區域 uiwait(msgbox(Please input the central locations of the four red points to cut the picture!)); % get the coordinates of the four points x_pix4 = []; y_pix4 = [];
finish=false; set(gcf,CurrentCharacter,@);
while ~finish % get the coordinates of the four points [x_pix1,y_pix1] = ginput(1); hold on plot(x_pix1,y_pix1,*g)
x_pix4 = [x_pix4 x_pix1]; y_pix4 = [y_pix4 y_pix1];
% check for keys key = get(gcf,CurrentCharacter); children = get(gca, children);
if key~=@ % has it changed from the dummy character? set(gcf,CurrentCharacter,@); % reset the character if strcmp (key, char(13)) break;
elseif strcmp(key, char(127)) && length(children)>2 delete(children(1)); delete(children(2)); x_pix4 = x_pix4(1:end-2); y_pix4 = y_pix4(1:end-2); continue; end
end end hold off
yMin = int16(min(y_pix4)); yMax = int16(max(y_pix4)); xMin = int16(min(x_pix4)); xMax = int16(max(x_pix4));
MM_new = MM_wrap(yMin:yMax,xMin:xMax,:); imagesc(MM_new)
%% 5.逐插針描畫其位置 % 獲取1釐米代表多少個像素點 pixels_height = size(MM_new,1)/26;
% pixels cover 1 cm width pixels_width = size(MM_new,2)/106;
uiwait(msgbox(describe the profile: from 1st to the last bin))
x_pixs = []; y_pixs = [];
while ~finish
[x_pix,y_pix] = ginput(1); hold on plot(x_pix,y_pix,*r)
x_pixs = [x_pixs x_pix]; y_pixs = [y_pixs y_pix];
if key~=@ % has it changed from the dummy character? set(gcf,CurrentCharacter,@); % reset the character if strcmp (key, char(13)), break; elseif strcmp(key, char(127)) && length(children)>2 delete(children(1)); delete(children(2)); x_pixs = x_pixs(1:end-2); y_pixs = y_pixs(1:end-2); continue; end end end
% 計算對應的長度和高度 x_widths = (x_pixs-x_pixs(1))/pixels_width; y_heights = -(y_pixs - max(y_pixs))/pixels_height;
x_intp = transpose(0:100); y_intp = interp1(x_widths,y_heights,x_intp,spline);
%% 6. 確認數字化後的結果 SW0 = screensize(:,3)*46/1920; SW = screensize(:,3)*1833/1920; SH0 = screensize(:,4)*735/1080; SH = screensize(:,4)*201/1080;
figure(Name,filename,position,[SW0 SH0 SW SH])
plot(x_intp,y_intp)
xlabel(Length (cm)) ylabel(Height (cm))
%% 保存結果
dir_result = [picturedir,2018_greece];
if ~isdir(dir_result)
mkdir(dir_result)
end
save([dir_result pointName,.mat],x_intp,y_intp)
%% continue or end? answer = questdlg(Would you like continue?, ... Make a choose, ... Continue,End Task,Continue);
% Handle response switch answer case Continue run roughness_extraction_V2.m; case End Task disp(Task End); end
disp(filename) disp(pointName)
推薦閱讀: