如何基于Azure对象检测输出裁剪图像



我在customvision.ai网站中有一个微软Azure对象检测模型。我使用它的API进行预测,然后将输出边界框绘制为图像中的矩形。以下是实现这一点的powershell代码:

#First powershell script
#API call to object detection model to predict objects and their bounding boxes
$filePath = "C:ImageOne.jpg"
$fileBytes = [System.IO.File]::ReadAllBytes($FilePath);
$Url = "<MyCustomVisionModelEndpoint>"
$headers = @{
'Prediction-Key' = $customVisionPredictionKey
'Content-Type' = 'application/octet-stream'
}
$proxy = [System.Net.WebRequest]::GetSystemWebProxy().GetProxy("https://<CustomVisionResourceName>.cognitiveservices.azure.com")
$APIresult = Invoke-RestMethod -Method 'Post' -Uri $url -Body $fileBytes -Headers $headers -UseDefaultCredentials -Proxy $proxy -ProxyUseDefaultCredentials
#Get Results and draw the predicted bounding boxes in the input image
$results = $APIresult.predictions | Where-Object {!$_.tagName.toString().contains("not") -and !$_.tagName.toString().contains("door") -and !$_.tagName.toString().contains("tyre") -and $_.probability -ge 0.02}
Add-Type -AssemblyName System.Drawing
$srcImage=[System.Drawing.Image]::FromFile($FilePath)
$height = $srcImage.height
$width = $srcImage.width
$graphics=[System.Drawing.Graphics]::FromImage($srcImage)
$pen = New-Object Drawing.Pen([System.Drawing.Color]::Blue,3);
$font = New-Object Drawing.Font("Arial", 7);
$brush = New-Object Drawing.SolidBrush([System.Drawing.Color]::Red);
foreach($result in $results)
{
$left = $width * $result.boundingBox.left
$top = $height * $result.boundingBox.top
$PHeight = $height * $result.boundingBox.height
$PWidth =  $width * $result.boundingBox.width
$rect = New-Object Drawing.Rectangle($left, $top, $PWidth, $PHeight);
$graphics.DrawRectangle($pen, $rect);
$tag = "Tag: " + $result.tagName + " ,Probability: " + [math]::Round($result.probability * 100,2)
$graphics.DrawString($tag,$font,$brush,$left, $top);
}
$graphics.Dispose()
if($results)
{
$srcImage.Save("D:Output.jpg")
}

假设我的对象检测模型预测了一个对象。现在我想使用这个预测的对象边界框,并用这些边界框坐标裁剪原始图像。以下是实现这一点的powershell代码:

#Second powershell script
Add-Type -AssemblyName System.Drawing
$filepath = "C:ImageOne.jpg"
$srcImage=[System.Drawing.Image]::FromFile($FilePath)
$srcRect = New-Object Drawing.Rectangle(0,0,$srcImage.Width,$srcImage.Height)
#Here left, top, width, height co-ordinates comes from above powershell code which does predictions and draws rectangular bounding boxes
$destRect = New-Object Drawing.Rectangle([UInt32]($left),[UInt32]($top),[UInt32]($PWidth),[UInt32]($PHeight))
$bmp=new-object System.Drawing.Bitmap($destRect.Width,$destRect.Height)
$graphics=[System.Drawing.Graphics]::FromImage($bmp)
#I tried with [System.Drawing.GraphicsUnit]::Pixel also, but no use
$units = [System.Drawing.GraphicsUnit]::Point
$destRect = new-object Drawing.Rectangle($destRect.Left, $destRect.Top, $destRect.Width, $destRect.Height)
$srcRect = new-object Drawing.Rectangle($srcRect.Left, $srcRect.Top, $srcRect.Width, $srcRect.Height)
$graphics.DrawImage($srcImage, $srcRect, $destRect, $units)
$graphics.Dispose()
$bmp.Save("D:test.jpg")

我在这个链接的帮助下准备了第二个powershell脚本:Powershell在System.Drawing 中使用.NET.DrawImage

第一个代码运行良好,我可以进行预测,在输入图像中绘制预测对象的边界框。

我在第二个脚本中使用了相同的预测边界框坐标,并试图裁剪预测的对象区域。但它的裁剪不正确。

第一个脚本正确地绘制了边界框,但第二个脚本正在裁剪图像的其他部分。

我认为第二个powershell脚本可能有一些错误。我不明白出了什么问题。有人能帮帮我吗?

在第二个powershell脚本中,我更改了位图如下:

$bmp=new-object System.Drawing.Bitmap($srcImage.Width,$srcImage.Height)

然后我把图形单元改成

[System.Drawing.GraphicsUnit]::Pixel

现在它按预期工作

最新更新