logo头像

Edward.K Thinking

Azure Custom Vision Region位置大小與像素座標的轉換

使用 Custom Vision 可以在Project Types類型中,選擇Object Detection類型,Object Detection類型專案是可以讓我們在圖片去標示想要識別的物件,標示的方式是透過一個白色框去 Tag 該物件。因此,在圖片中定義要辨識的物件方框,稱為Region


Custom Vision的Region在圖片的位置與大小,是透過一組起始座標XY和框的大小所產生的。在這裡的XY座標位置,是代表座標點與圖邊的距離來呈現的。不過,一般在實務上要去框住圖片的某物件,會是使用方框的兩個對角線座標來建立,且用X1Y1和X2Y2來代表這個方框在圖片中的位置。而XY數值也不是代表這個點與圖邊的距離。反而是用像素來作為XY座標,這樣的好處在於當這張圖片的大小改變時候,方框的位置還是可以依舊準確對應到我們想要框住的物件,何謂像素座標,如下圖。


若是上圖紅色點代表在圖的位置是135,144像素,這個點的座標就會是X=135、Y=144,如果我們是把對角線的兩個座標值,是無法套用到Azure Custom Vision的Region,必須做轉換,且如果把像素單位的座標,作為Region的座標,會發現定義圖片物件的位置會非常的奇怪,因此,要如何將像素座標進行轉換成Custom Vision的Region資訊,需進行四個步驟

  • X座標轉換成離圖片左邊邊框的距離
  • Y座標轉換成離圖片上方邊框的距離
  • 計算出Region的寬度
  • 計算出Region的長度

要進行上面四個步驟,必須先將第一個像素座標點,轉換成距離,而這邊的單位都是像素

  • Region Left = X1 / Image Width
  • Region Top = Y1 / Image Height
  • Region Width = (X2 - X1) / image Width
  • Region Height = (Y2 - Y1) / image Height

因此第一步就是取得圖片的大小像素

1
2
3
4
5
byte[] imageBytes
ImageWh imageWh = new ImageWh();
System.Drawing.Image image = System.Drawing.Image.FromStream(new System.IO.MemoryStream(imageBytes));
imageWh.Width = image.Width;
imageWh.Height = image.Height;

若是圖片從網址取得的方式

1
2
3
4
5
6
ImageWh imageWh = new ImageWh();
byte[] imageData = new WebClient().DownloadData(imageUrl);
MemoryStream imgStream = new MemoryStream(imageData);
System.Drawing.Image img = System.Drawing.Image.FromStream(imgStream);
imageWh.Height = img.Height;
imageWh.Width = img.Width;

因此,就可以得到圖片長高的像素。這時候再寫一個轉換的函示,imageWidthimageheigh代表圖片的長寬像素

1
2
3
4
5
6
7
8
9
10
11
public ImageBoxlocation GetBoxlocation(double imageWidth, double imageheigh, ImageBoxCoordinate imageBoxCoordinate)
{
ImageBoxlocation boxlocation = new ImageBoxlocation
{
Left = imageBoxCoordinate.X1 / imageWidth,
Top = imageBoxCoordinate.Y1 / imageheigh,
Width = (imageBoxCoordinate.X2 - imageBoxCoordinate.X1) / imageWidth,
Height = (imageBoxCoordinate.Y2 - imageBoxCoordinate.Y1) / imageheigh
};
return boxlocation;
}

藉由上面兩個轉換後,就可取得 Region 的資訊並套用進去

上一篇