主頁 > 軟體設計 > 我用 MATLAB 提取圖片曲線

我用 MATLAB 提取圖片曲線

2021-08-19 08:01:18 軟體設計

文章目錄

    • 我用 MATLAB 提取圖片曲線
      • 行文動機
      • 影像的讀入與裁剪
      • 顏色拾取
      • 顏色轉換與色差計算
      • 分離曲線
      • 二值化,提取資料
      • 資料點分類與排序
      • 后話

我用 MATLAB 提取圖片曲線

給你一張圖片,如何提取里面曲線的資料,從而利用這些資料進行影像重繪、加工處理、測距、擬合得到函式運算式等操作呢?

行文動機

前段時間,有個朋友問了我一個問題,大概意思就是要給影像的流線測距離,在我的印象里面,MATLAB 是似乎沒有這種直接的功能的,

在這里插入圖片描述

那么換個角度來理解一下這個問題,如果給你一張影像,如何提取里面點的資料?其實,有了曲線的資料,后面想干嘛就干嘛了,

一直沒空弄這個,今天偷閑,安排!!!

影像的讀入與裁剪

以下面的影像作為例子,

在這里插入圖片描述

我們先匯入影像,進行簡單的裁剪,為什么要裁剪呢?其實不裁剪也沒關系,因為我后面是基于像素點的顏色來提取的曲線,如果你想提取的曲線不能通過顏色區分,那么,最好通過裁剪,把你不想要的部分盡可能地剪掉,

%% 讀入圖片,展示,有必要的話可以適當做一些裁剪
A = imread('a.jpg');%讀取到一張圖片
imshow(A);
A = imcrop(A);%使用滑鼠裁剪一波
imshow(A);
[low_num,col_num,~] = size(A);

顏色拾取

觀察影像發現,我們要提取的曲線是藍色的,所以我希望通過顏色把它區分出來,那么我們就要知道這個曲線的 RGB 值,我希望通過滑鼠點選的方式獲取到顏色值,

這里我偷個懶,直接采用了 slandarer 開源的顏色提取工具,這個模塊不是我寫的,特此宣告,請尊重原創,

%% 顏色提取
getcolor();
color = color_list_temp(1,:);
function getcolor
global control;
global ima;
global GUI;
global x_limit;
global y_limit;
global color;
global a;
global color_number;
global color_list;
global page;
global total_page;
global color_list_temp;
color=[];
page=1;
total_page=2;
color_list=[0 0 0];
color_list(1,:)=[];
color_number=1;
rgb_type=1;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
GUI.fig=figure('units','pixels',...
    'position',[350 100 800 500],...
    'Numbertitle','off',...
    'menubar','none',...
    'resize','off',...
    'name','getcolor',...
    'color',[0.95 0.95 0.95]);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
uh1=uimenu('label','設定');
uimenu(uh1,'label','RGB型別設定','callback',@RGBset)
    function RGBset(~,~)
        GUI.rgbfig=figure('units','pixels',...
        'position',[360 370 180 200],...
        'Numbertitle','off',...
        'menubar','none',...
        'name','RGBset',...
        'resize','off');
        GUI.axes=axes('Units','pixels',...
         'parent',GUI.rgbfig,...  
        'PlotBoxAspectRatio',[1 1 1],...
        'Color',[0.95 0.95 0.95],...
        'Box','on', ...
        'XLim',[0 500],...
        'YLim',[0 500], ...
        'XColor',[0.95 0.95 0.95],...
        'YColor',[0.95 0.95 0.95],...
        'YDir','reverse', ...
        'xtick',[],'ytick',[]);
        GUI.checkbox1=uicontrol('parent',GUI.rgbfig,...
            'style','checkbox',...
            'string','范圍:0-1',...
            'position',[45 150 400 30],...
            'fontsize',10,...
            'value',rgb_type,...
            'callback',@ifon1);
        GUI.checkbox255=uicontrol('parent',GUI.rgbfig,...
            'style','checkbox',...
            'string','范圍:0-255',...
            'position',[45 120 400 30],...
            'fontsize',10,...
            'value',~rgb_type,...
            'callback',@ifon255);
        GUI.makesurebutton=uicontrol('parent',GUI.rgbfig,...
            'style','pushbutton',...
            'string','確定設定',...
            'position',[45 70 100 25],...
            'fontsize',10,...
            'callback',@settype);
        
        function ifon1(~,~)
            if(get(GUI.checkbox1,'value')==1)
                set(GUI.checkbox1,'value',1);
                set(GUI.checkbox255,'value',0);
            else
                set(GUI.checkbox1,'value',1);
            end               
        end
        function ifon255(~,~)
            if(get(GUI.checkbox255,'value')==1)
                set(GUI.checkbox255,'value',1);
                set(GUI.checkbox1,'value',0);
            else
                set(GUI.checkbox255,'value',1);
            end                
        end
        function settype(~,~)
            rgb_type=get(GUI.checkbox1,'value');
            if ~isempty(color)
                set(GUI.text2,'string',['[',num2str((color/255).*rgb_type+color.*(~rgb_type)),']']);
            end
            show_color(page);
            close(GUI.rgbfig)
        end      
    end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
uh2=uimenu('label','保存');
uimenu(uh2,'label','儲存為mat','callback',@saveas_mat)
uimenu(uh2,'label','儲存為txt','callback',@saveas_txt)
uimenu(uh2,'label','儲存為excel','callback',@saveas_exl)
uimenupic=uimenu(uh2,'label','儲存為對照圖');
uimenu(uimenupic,'label','儲存全部頁碼','callback',@saveas_pic_all);
uimenu(uimenupic,'label','儲存當前頁碼','callback',@saveas_pic_now);
function saveas_mat(~,~)
    try
    [filename, pathname] = uiputfile({'*.mat','mat'});
        color_list_temp=(color_list/255).*rgb_type+color_list.*(~rgb_type);
        save([pathname,filename],'color_list_temp');
    catch
    end  
end
function saveas_txt(~,~)
    try 
    [filename, pathname] = uiputfile({'*.txt','記事本'});
        color_list_temp=(color_list/255).*rgb_type+color_list.*(~rgb_type);
        [m,n]=size(color_list_temp);
        fid=fopen([ pathname,filename],'w');
        for ii=1:m
            for jj=1:n
                if jj==n
                    fprintf(fid,'%d\r\n',color_list_temp(ii,jj));
                else
                    fprintf(fid,'%d\r\t',color_list_temp(ii,jj));
                end
            end
        end
        fclose(fid);
    catch
    end
end
function saveas_exl(~,~)
    [filename, pathname] = uiputfile({'*.xlsx','記事本'});
    color_list_temp=(color_list/255).*rgb_type+color_list.*(~rgb_type);
    xlswrite([ pathname,filename],color_list_temp) 
    
end
function saveas_pic_all(~,~)
    page_with_color=total_page-1;
    px=50;
    gap_px=10;
    pic=ones(9*px,page_with_color*px+(page_with_color-1)*gap_px,3);
    for p=1:page_with_color
        for ii=(p-1)*9+1:p*9
            for kk=1:3
                if ii<=length(color_list)
                    pic((ii-(p-1)*9-1)*px+1:(ii-(p-1)*9)*px,(p-1)*(px+gap_px)+1:(p-1)*(px+gap_px)+px,kk)=color_list(ii,kk)/255;     
                end
            end
        end
    end
    [filename, pathname] = uiputfile({'*.jpg;*.png','All Image Files';...
            '*.jpg','JPG';'*.png','PNG' });
    imwrite(pic,[pathname,filename]);
end
function saveas_pic_now(~,~)
    try
    [m,~]=size(color_list);
    m=m-(page-1)*9;
    m(m>9)=9;
    px=50;
    pic=ones(9*px,1*px,3);
    if m>0
        for ii=(page-1)*9+1:(page-1)*9+m
            for kk=1:3
                pic((ii-1)*px+1:ii*px,1:px,kk)=color_list(ii,kk)/255;      
            end
        end
    else
    end
    [filename, pathname] = uiputfile({'*.jpg;*.png','All Image Files';...
            '*.jpg','JPG';'*.png','PNG' });
    imwrite(pic,[pathname,filename]);
    catch
    end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%uh3=uimenu('label','匯入');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
GUI.text=uicontrol('parent',GUI.fig,...
    'style','text',...
    'string','色彩識別',...
    'horizontalalign','center',...
    'position',[50 440 400 30],...
    'backgroundcolor',[0.85 0.89 0.85],...
    'foregroundcolor','k',...
    'fontsize',15);
GUI.text1=uicontrol('parent',GUI.fig,...
    'style','text',...
    'string','',...
    'horizontalalign','center',...
    'position',[460 330 100 100],...
    'backgroundcolor',[1 1 1],...
    'foregroundcolor','k',...
    'fontsize',10);
GUI.text2=uicontrol('parent',GUI.fig,...
    'style','text',...
    'string','',...
    'horizontalalign','center',...
    'position',[350 440 210 30],...
    'backgroundcolor',[1 1 1],...
    'foregroundcolor','k',...
    'fontsize',10);
GUI.savecolorbutton=uicontrol('parent',GUI.fig,...
    'style','pushbutton',...
    'string','儲存顏色',...
    'position',[460 290 100 30],...
    'backgroundcolor',[0.85 0.89 0.85],...
    'foregroundcolor','k',...
    'fontsize',15,...
    'callback',@save_color);
GUI.deletedatabutton=uicontrol('parent',GUI.fig,...
    'style','pushbutton',...
    'string','清空資料',...
    'position',[460 230 100 30],...
    'backgroundcolor',[0.8 0.9 0.9],...
    'foregroundcolor','k',...
    'fontsize',15,...
    'callback',@clear_data);
GUI.deletepicbutton=uicontrol('parent',GUI.fig,...
    'style','pushbutton',...
    'string','洗掉圖片',...
    'position',[460 180 100 30],...
    'backgroundcolor',[0.8 0.9 0.9],...
    'foregroundcolor','k',...
    'fontsize',15,...
    'callback',@delete_pic);
GUI.getcapbutton=uicontrol('parent',GUI.fig,...
    'style','pushbutton',...
    'string','螢屏截圖',...
    'position',[460 130 100 30],...
    'backgroundcolor',[0.8 0.9 0.9],...
    'foregroundcolor','k',...
    'fontsize',15,...
    'callback',@get_capture);
GUI.getpicbutton=uicontrol('parent',GUI.fig,...
    'style','pushbutton',...
    'string','讀取圖片',...
    'position',[460 80 100 30],...
    'backgroundcolor',[0.8 0.9 0.9],...
    'foregroundcolor','k',...
    'fontsize',15,...
    'callback',@getImage);
GUI.getcolorbutton=uicontrol('parent',GUI.fig,...
    'style','pushbutton',...
    'tag','recc',...
    'string','獲取顏色',...
    'position',[460 30 100 30],...
    'backgroundcolor',[0.8 0.9 0.9],...
    'foregroundcolor','k',...
    'fontsize',15,...
    'callback',@get_color);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for i=1:9
    GUI.text=uicontrol('parent',GUI.fig,...
    'tag',num2str(i),...
    'style','text',...
    'string','',...
    'horizontalalign','left',...
    'position',[600 440-40*(i-1) 30 30],...
    'backgroundcolor',[1 1 1],...
    'foregroundcolor','k',...
    'fontsize',10);    
end

for i=1:9
    GUI.text=uicontrol('parent',GUI.fig,...
    'tag',[num2str(i),'t'],...
    'style','text',...
    'string','',...
    'horizontalalign','center',...
    'position',[640 440-40*(i-1) 150 30],...
    'backgroundcolor',[1 1 1],...
    'foregroundcolor','k',...
    'fontsize',8);    
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
GUI.inputbutton=uicontrol('parent',GUI.fig,...
    'style','pushbutton',...
    'string','清除最后一個顏色',...
    'position',[600 80 190 30],...
    'backgroundcolor',[0.85 0.89 0.85],...
    'foregroundcolor','k',...
    'fontsize',15,...
    'callback',@delete_last);
%GUI.inputbutton=uicontrol('parent',GUI.fig,...
    %'style','pushbutton',...
    %'string','匯出資料',...
    %'position',[600 30 190 30],...
    %'backgroundcolor',[0.85 0.89 0.85],...
    %'foregroundcolor','k',...
    %'fontsize',15,...
    %'callback',@output_data);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
GUI.lpbutton=uicontrol('parent',GUI.fig,...
    'style','pushbutton',...
    'string','<上一頁',...
    'position',[600 30 70 30],...
    'backgroundcolor',[0.85 0.85 0.85],...
    'foregroundcolor','k',...
    'fontsize',12,...
    'callback',@lastpage);
GUI.npbutton=uicontrol('parent',GUI.fig,...
    'style','pushbutton',...
    'string','下一頁>',...
    'position',[720 30 70 30],...
    'backgroundcolor',[0.85 0.85 0.85],...
    'foregroundcolor','k',...
    'fontsize',12,...
    'callback',@nextpage);
GUI.page=uicontrol('parent',GUI.fig,...
    'style','text',...
    'string',[num2str(page),'/',num2str(total_page)],...
    'horizontalalign','center',...
    'position',[670 30 50 27],...
    'backgroundcolor',[0.95 0.95 0.95],...
    'foregroundcolor','k',...
    'fontsize',12);
function lastpage(~,~)
    page=page-1;
    page(page<1)=1;
    set(GUI.page,'string',[num2str(page),'/',num2str(total_page)]);
    show_color(page);
end
function nextpage(~,~)
    page=page+1;
    page(page>total_page)=total_page;
    set(GUI.page,'string',[num2str(page),'/',num2str(total_page)]);
    show_color(page);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
GUI.axes=axes('Units','pixels',...
      'PlotBoxAspectRatio',[1 1 1],...
      'Position',[50 30 400 400],...
      'Color',[0.98 0.98 0.98],...
      'Box','on', ...
      'XLim',[0 500],...
      'YLim',[0 500], ...
      'XColor','w','YColor','w',...
      'YDir','reverse', ...
      'Tag','picbagaxes',...
      'xtick',[],'ytick',[]);
hold on;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %function output_data(~,~)
        %if color_number>1
            %disp(color_list)
        %end
    %end
    function show_color(cur_page)
        len_list=size(color_list,1);
        for ii=(cur_page-1)*9+1:(cur_page-1)*9+9
            if(ii<=len_list)
                set(findobj('tag',num2str(ii-(cur_page-1)*9)),'backgroundcolor',color_list(ii,:)/255)
                set(findobj('tag',[num2str(ii-(cur_page-1)*9),'t']),'string',['[',num2str((color_list(ii,:)/255).*rgb_type+color_list(ii,:).*(~rgb_type)),']'])
            else
                set(findobj('tag',num2str(ii-(cur_page-1)*9)),'backgroundcolor',[1 1 1])
                set(findobj('tag',[num2str(ii-(cur_page-1)*9),'t']),'string','')
            end
        end  
    end

    function save_color(~,~)
        if ~isempty(get(GUI.text2,'string'))
            %set(findobj('tag',num2str(color_number)),'backgroundcolor',color/255)
            %set(findobj('tag',[num2str(color_number),'t']),'string',['[',num2str((color/255).*rgb_type+color.*(~rgb_type)),']'])
            color_list(color_number,:)=color;%(color/255).*rgb_type+color.*(~rgb_type);
            color_number=color_number+1;
            if color_number-1>(total_page-1)*9
                page=ceil(color_number/9);
                total_page=total_page+1;
                set(GUI.page,'string',[num2str(page),'/',num2str(total_page)]);
                
            end
            show_color(page)
        end
    end

    function delete_last(~,~)
        if color_number>=1
            %set(findobj('tag',num2str(color_number-1)),'backgroundcolor',[1 1 1])
            %set(findobj('tag',[num2str(color_number-1),'t']),'string','')
            color_list(end,:)=[];
            color_number=color_number-1;
            if color_number-2<=(total_page-2)*9
                page=ceil((color_number-1)/9);
                total_page=total_page-1;
                set(GUI.page,'string',[num2str(page),'/',num2str(total_page)]);
                
            end
            show_color(page)
        end
    end

    function delete_pic(~,~)
        control=0;
        set(findobj('Tag','picbagaxes'),...
        'XLim',[0 500],...
        'YLim',[0 500],...
        'Position',[50 30 400 400],...
        'Color',[0.98 0.98 0.98]);
        delete(a);
    end

    function clear_data(~,~)
        control=0;
        set(GUI.text1,'backgroundcolor',[1 1 1]);
        set(GUI.text2,'string','');
        set(findobj('Tag','picbagaxes'),...
        'XLim',[0 500],...
        'YLim',[0 500],...
        'Position',[50 30 400 400],...
        'Color',[0.98 0.98 0.98]);
        set(findobj('tag','recc'),'string','獲取顏色');
        delete(a);
    end

    function get_color(~,~)
        if control==0
            set(GUI.text1,'backgroundcolor',[1 1 1]);
            set(GUI.text2,'string','');       
        end
        control=1;
        set(gcf,'WindowButtonMotionFcn',@whilemovefcn)  
        set(gcf,'WindowButtonDownFcn',@whileclickfcn)
    end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function whilemovefcn(~,~)
        xy=get(gca,'CurrentPoint');
        x=xy(1,2);y=xy(1,1);
        if x<=x_limit&&y<=y_limit&&x>=0&&y>=0
            x(x>x_limit)=x_limit;
            y(y>y_limit)=y_limit;
            x(x<1)=1;
            y(y<1)=1;
            x=round(x);
            y=round(y);
            if control==1
                color=double([ima(x,y,1),ima(x,y,2),ima(x,y,3)]);
                set(GUI.text1,'backgroundcolor',color/255);
                set(GUI.text2,'string',['[',num2str((color/255).*rgb_type+color.*(~rgb_type)),']']);
            end
        else
            if control==1
                set(GUI.text1,'backgroundcolor',[1 1 1]);
                set(GUI.text2,'string','');    
            end
        end
    end

    function whileclickfcn(~,~)          
            xy=get(gca,'CurrentPoint');
            x=xy(1,2);y=xy(1,1);
            if x<=x_limit&&y<=y_limit&&x>=0&&y>=0
                control=0;
                set(GUI.text1,'backgroundcolor',color/255);
                set(GUI.text2,'string',['[',num2str((color/255).*rgb_type+color.*(~rgb_type)),']']);
                set(findobj('tag','recc'),'string','繼續取色');
                %disp(color/255)
            end
    end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function get_capture(~,~)
        screensize=get(0,'screensize');
        screensize=1.5*screensize;
        robot=java.awt.Robot();
        rectangle=java.awt.Rectangle();
        rectangle.x=0;
        rectangle.y=0;
        rectangle.width=screensize(3);
        rectangle.height=screensize(4);
        image=robot.createScreenCapture(rectangle);
        data=image.getData(); 
        temp=zeros(screensize(3)*screensize(4)*3,1);
        temp=data.getPixels(0,0,screensize(3),screensize(4),temp);  
        temp=uint8(temp);
        R=temp(1:3:end); 
        G=temp(2:3:end); 
        B=temp(3:3:end);
        R=reshape(R,[screensize(3),screensize(4)]); 
        G=reshape(G,[screensize(3),screensize(4)]); 
        B=reshape(B,[screensize(3),screensize(4)]);
        R=R';
        G=G';
        B=B';
        x_limit=screensize(4); 
        y_limit=screensize(3);
        leng=max([x_limit,y_limit]);
        set(findobj('Tag','picbagaxes'),...
        'XLim',[0 leng],...
        'YLim',[0 leng]);
        ima=cat(3,R,G,B);
        delete(a);
        a=imshow(ima);
    end
    function getImage(~,~)
        warning off;
        try
        [filename, pathname] = uigetfile({'*.jpg;*.tif;*.png;*.gif','All Image Files';...
            '*.*','All Files' });
        ima = imread([ pathname,filename]);
        [x,y,~]=size(ima);
        x_limit=x;y_limit=y;
        leng=max([x_limit,y_limit]);
        set(findobj('Tag','picbagaxes'),...
        'XLim',[0 leng],...
        'YLim',[0 leng]);
        delete(a);
        a=imshow(ima);
        catch
        end
    end  
end

在這里插入圖片描述

顏色轉換與色差計算

用 RGB 比較顏色之間的相似度時,存在很大的問題,不建議直接使用,因為往往一個通道的一點改變,會導致最后融合在一起的顏色發生巨大變化,而如果三個通道的同時改變,卻只會使最后的明暗發生變化,色調并不會產生巨大變化,而這也是H系列色彩空間普遍存在的問題,

所以,經過思考,我決定 RGB 的值轉為 HSV 顏色空間,再進行色差計算,

在這里插入圖片描述

色差計算,直接利用兩個點的顏色在椎體上的歐式距離,即通過計算如下坐標點的歐式距離,我們通過撰寫 color_dist 函式計算,

%計算兩個 HSV 顏色之間的距離
function d = color_dist(color_std,color)
[x0,y0,z0] = getPos(color_std(1),color_std(2),color_std(3));
[x,y,z] = getPos(color(1),color(2),color(3));
d = sqrt((x-x0).^2+(y-y0).^2+(z-z0)^2);
end

function [x,y,z] = getPos(H,S,V)
r = 1;
h = sqrt(3);
x = r*V*S*cos(H);
y = r*V*S*sin(H);
z = h*(1-V);
end

在這里插入圖片描述

%% 顏色轉為 HSV,再進行色差計算
A2 = rgb2hsv(A);
color2 = rgb2hsv(color);
D = ones(low_num,col_num)*2;
for i=1:low_num
    for j=1:col_num
        D(i,j) = color_dist(color2,A2(i,j,:));
    end
end
mesh(D);

分離曲線

通過調節閾值引數,可以把我們想要的坐標軸過濾掉,閾值越小,過濾效果越明顯,

%% 根據色彩,把想要的曲線分離出來
threshold = 0.5;%可以調整閾值使分離效果變好
I = (D<threshold);
for i=1:3
    RGB= A(:,:,i);
    RGB(~I)=255;
    A3(:,:,i) = RGB;
end
imshow(A3)

在這里插入圖片描述

二值化,提取資料

二值化影像是以矩陣形式存盤的,我們根據色素點在矩陣中的位置,利用行列指標和坐標軸的標準化關系,提取資料,重建坐標系,

%% 二值化,提取資料
leftUp = [0,1];%標注截取的圖片的左上角和右下角
rightDown = [1,0];
B = rgb2gray(A3);
imshow(B);
[pos_row,pow_col] = find(B~=255);
Ps = [pos_row-1,pow_col-1];
Ps(:,1) = Ps(:,1)./(low_num-1);
Ps(:,2) = Ps(:,2)./(col_num-1);
x = (rightDown(1)-leftUp(1)).*Ps(:,2)+leftUp(1);
y = leftUp(2)-abs(rightDown(2)-leftUp(2)).*Ps(:,1);
scatter(x,y,0.38);
X = [x,y];

在這里插入圖片描述

看著八九不離十了,但是注意這里的坐標點是以散點的形式畫出來的,是無序且沒有區分度的,我們甚至無法使用plot

資料點分類與排序

肉眼可見,這幾條曲線是分隔開的,我們如何把這些資料按曲線分開且其上的點按順序排好呢?我的做法是,使用滑鼠選中你在意的曲線的一端,利用距離延拓法,還原整條曲線,

%% 資料分類與排序
N = size(X,1);
gfrom = ginput(1);
[~,minI] = min(sum((X - repmat(gfrom,N,1)).^2,2));
from = X(minI,:);
X(minI,:) = [];
X = [from;X];
tol = 0.01;
X1 = findcurvepath(X,tol);
plot(X1(:,1),X1(:,2))

其中用到了一個自己寫函式 findcurvepath,它可以從一個資料點出發,把所有的資料點按距離遠近,像串珍珠一樣串在一塊,

function ps1 = findcurvepath(ps0,tol)
%這個函式將點就近連接起來
ps1(1,1:2) = ps0(1,1:2);%將第一個取出來
ps0 = ps0(2:end,:);%ps0重置為剩下的部分
p = ps1(end,:);%p是取出來的最后一個
while ~isempty(ps0)
    
    i = 1;
    while 1
        distances = p2psdistance(p,ps0);
        inds = find(distances == min(distances));%%%%%%%修復一個bug
        if length(inds) > 1
            if size(ps1,1)<i+1
                break;
            end
            p = ps1(end-i,:);%p是取出來的最后一個
            i = i+1;
        else
            break;
        end
    end
    
    distances = p2psdistance(p,ps0);
    if min(distances)>tol
        break;
    end
    inds = find(distances == min(distances));%%%%%%%修復一個bug
    ind = inds(1);
    ps1(end+1,1:2) = ps0(ind,1:2);
    ps0(ind,:) = [];
    p = ps1(end,:);
end
end
function distances = p2psdistance(p,ps)
distances = sqrt((p(1)-ps(:,1)).^2+(p(2)-ps(:,2)).^2);
end

在這里插入圖片描述

后話

我不喜歡做 GUI,因為亂七八糟的界面用起來確實令人心煩,另外一方面,不管是 GUI 或者說進一步的 exe 桌面程式,都依賴于 MATLAB 的環境,也就是說,你要運行代碼,就必須先裝 MATLAB 的環境,試想,一個安裝過和簡單用過 MATLAB 的人,都是有能力可以通過代碼修改一些引數的,那么你做 GUI 不是畫蛇添足么,

完整版的代碼到評論中的鏈接中下載,

為了方便使用,我還寫一個簡單的說明檔案,我把它和完整版代碼一起打包放到了評論中的鏈接里,有任何問題可以咨詢,

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/294753.html

標籤:其他

上一篇:劍指offer系列——劍指 Offer 03. 陣列中重復的數字(C語言)

下一篇:復雜網站的爬取實踐

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more