matlab從曲線圖提取數據


同學用肉體一頓飯讓我幫他做下這個DDL

樣圖是一張非常扭曲的三虛線圖他甚至想OCR識別x軸y軸坐標單位

  • 上谷歌查了查,對於曲線圖提取數據基本上是手動在曲線上取幾個點,然后由這個幾個點開始遍歷領域點,判斷領域點是否是黑色,然后再遍歷這個黑色點的領域,最終找出一條最長的線便是曲線,一種類似曲線擬合的做法?
  • 知乎專欄提供了一種思路,先把曲線圖上無關信息去掉,然后提取最大的連通區域,就是所需要的實線,只可惜樣例圖要做的是虛線
    第一種方法是同學AA想要的,不過英國人嘛,只告訴他要這樣做,並沒有告訴他基本思想,所以我們基於第二種方法拓展嘗試一下。

清洗圖像

所給的圖像是RGB圖像,且有噪聲點,先將圖像灰度化,計算圖像閾值,通過閾值將圖像二值化。

提取真實區域

想要的真實區域就是下圖中使用紅框標出的區域

法1

一開始的想法是先在圖片的(end*0.8:end-10,)區域中霍夫變換識別出下邊框,然后取下邊框的(,1:10)部分識別左邊框,取左邊框的最上端坐標和下邊框的最右端坐標,作為分割圖像的基准,真實區域就分割出來了。

  • 提取下邊框很順利
  • 提取左邊框不是很順利
  • 提取右邊框也不是很順利
  • 提取上邊框很順利

    雖然和計划的有所偏差,但通過上邊框的最左端坐標和下邊框的最右段坐標,作為分割圖像的基准,得到的真實圖像理論上是相同的。

法2

對於樣例圖,真實區域是封閉的,是圖中的最大連通區域,那找最大聯通區域也可以提取出樣例圖的真實區域。

再取得該區域最左上端白點坐標和最右下端白點坐標,作為分割圖像的基准,得到真實圖像。
真實圖像如圖所示

再次清洗圖像

為了方便起見,下文中“圖”、“圖像”指的是上一步中得到的真實圖像,而不是原始圖像。
對於得到的圖像,仍然存在邊框、刻度線、右下角標識區域等無關信息。

  • 邊框可以直接通過上一步法1中得到的邊框坐標數組去掉。
  • 刻度線以左邊框的刻度線為例,遍歷圖像(,1:5)范圍內,若該點是黑點,則從該點開始,向右尋找最大的直線區域,去除。
    樣例圖中存在曲線與刻度線相交的情況,我采用的方法是對於該點,如果24領域中的黑點總數大於一個閾值,則認為該點是曲線上的點,保留。
  • 右下角標識區域直接找取聯通區域,如果該連通區域的大小大於閾值,認為是標識區域,去除。
    得到的結果圖像,邊界存在問題,有待改進:

分離曲線

三條曲線都不是實線,沒法通過找最大聯通區域的方法逐個分離,但因為不同曲線中實線部分的長度是不一樣的,所以可以貪心一下,從第1列開始,以某個閾值add_len為步長,找最大連通區域,再進行拼接,以圖中最上面一條曲線為例:

  • 首先取圖像(:,1:10)區域中的最大聯通區域,或者取3個聯通區域,認為聯通區域在列上的坐標極小值為其高度值,高度值越小則越高,最高者則為想要取得最上面一條曲線。
  • 然后取得該聯通區域中最右端的點n1(x,y),再取(:,y+1:y+add_len)中的n個聯通區域,對於每個聯通區域,找出其最左端的點n2(x1,y1),求n1與n2之間的歐式距離,認為歐式距離最短的就是該曲線在(:,y+1:y+add_len)的部分,然后重復該步,直到y值無限接近於圖像最右端。
  • 對於上一步也有不同的做法,取得該聯通區域中最右端的點n1(x,y),在從i=1開始循環,取(:,y+1:y+add_len)中的i個最大聯通區域,對於第i個區域,他的面積總是第i大的,找出其最左端的點n2(x1,y1),求n1與n2之間的歐式距離,若歐式距離小於某個閾值,則認為該聯通區域是該曲線在(:,y+1:y+add_len)的部分,然后重復該步,直到y值無限接近於圖像最右端。
    過程如圖:

    兩種做法進行比較,得出的曲線基本相同。
    取得最上端曲線a如圖所示:

    然后將該曲線在圖中去除,再重復之前的做法,取得第二條曲線b。對於第二條曲線,add_len需要改小,歐式距離的閾值需要改大。

    將第二條曲線去除,得到第三條曲線c

    可以看出第三條曲線的圖像存在噪點,可以用一個區域對噪點清洗,得到第三條曲線c

導出數據

將a,b,c的坐標值與圖像的size相除,再乘上單位,即可得到數據。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM