スクリプトタスクで画像を加工して保存する方法

本トピックでは、MENOU-TE v1.41.702 より追加された機能を使って、スクリプトタスクで画像を保存する方法を紹介します。

概要

スクリプトタスクでは任意タスクの解析結果を利用して、独自の処理を行うことができます。
例えば、欠陥の座標や面積をCSVなどに保存するのが代表的な使い方です。

CSVなどのテキスト情報に加えて、欠陥の画像を保存したいというケースもあると思います。
MENOU-TE v1.41.702 にて画像を保存しておくための便利な機能が追加されましたので、使い方を紹介します!

実際に保存できる画像例

スクリプトタスクを利用して保存できる画像の例を紹介します。
利用したワークスペースはサンプルワークスペースのプリント基板です。

元画像

GetImage() というメソッドを利用すると、入力画像が取得できます。

var inputImage = GetImage();
if (inputImage != null)
{
    inputImage.SaveImage(Path.Combine(baseDir, "original.png"));
}

ヒートマップ画像

任意のタスクを取得して CreateHeatMapImage() というメソッドを利用すると、そのタスクのヒートマップ画像が取得できます。
※従来から可能

var sampleResult = GetPredictionTaskResult("サンプル全体") as ISegmentationTaskResult;
if (sampleResult != null)
{
    // ヒートマップ画像
    var heatMapImage = sampleResult.CreateHeatMapImage();
    heatMapImage.SaveImage(Path.Combine(baseDir, "heatmap.png"));
}

元画像とヒートマップを重ねた画像

元画像とヒートマップ画像は、Paste() というメソッドを利用すると、重ねることができます。

// 合成画像(入力画像にヒートマップを透過させて重ねる)
var blendedImage = inputImage.Paste(heatMapImage, 0, 0, 0.5);
blendedImage.SaveImage(Path.Combine(baseDir, "blend.png"));

欠陥位置(ブロブ)で切り取った画像

任意のタスクのブロブを取得すると、画像をその位置で切り取ることができます。

// ブロブ位置で切り取り
foreach (var blob in sampleResult.Blobs)
{
    var blobBlendedImage = blendedImage.Crop(blob);
    blobBlendedImage.SaveImage(Path.Combine(baseDir, $"blend_{blob.X}_{blob.Y}.png"));
}

矩形描画

任意のタスクのブロブを、矩形で描画することもできます。

// 矩形描画用画像
var rectImage = GetImage();

// 検出したブロブ毎に処理
foreach (var blob in sampleResult.Blobs)
{
    // 入力画像に矩形描画
    rectImage.DrawRectangle(blob, Color.Red, thickness:12, margin: 16);
}
        
// 矩形描画結果を保存
rectImage.SaveImage(Path.Combine(baseDir, "rect.png"));

スクリプト全体例

以上の処理をまとめたスプリプト例です。

// 検査をしない場合はnull 条件に一致する場合はtrue 条件に一致しない場合はfalse
using System.Drawing;

bool? result = false;

var baseDir = "C:\\work\\test";
Directory.CreateDirectory(baseDir);

// 入力画像
var inputImage = GetImage();
if (inputImage != null)
{
    inputImage.SaveImage(Path.Combine(baseDir, "original.png"));
    
    // 矩形描画用画像
    var rectImage = GetImage();
    
    var sampleResult = GetPredictionTaskResult("サンプル全体") as ISegmentationTaskResult;
    if (sampleResult != null)
    {
        // ヒートマップ画像
        var heatMapImage = sampleResult.CreateHeatMapImage();
        heatMapImage.SaveImage(Path.Combine(baseDir, "heatmap.png"));
        
        // 合成画像(入力画像にヒートマップを透過させて重ねる)
        var blendedImage = inputImage.Paste(heatMapImage, 0, 0, 0.5);
        blendedImage.SaveImage(Path.Combine(baseDir, "blend.png"));
        
        // 検出したブロブ毎に処理
        foreach (var blob in sampleResult.Blobs)
        {
            // 入力画像をブロブ位置で切り取り
            var blobInputImage = inputImage.Crop(blob);
            blobInputImage.SaveImage(Path.Combine(baseDir, $"original_{blob.X}_{blob.Y}.png"));
            
            // ヒートマップをブロブ位置で切り取り
            var blobHeatMapImage = heatMapImage.Crop(blob);
            blobHeatMapImage.SaveImage(Path.Combine(baseDir, $"heatmap_{blob.X}_{blob.Y}.png"));
            
            // ブロブ位置で切り取った画像を合成
            var blobBlendedImage = blobInputImage.Paste(blobHeatMapImage, 0, 0, 0.5);
            blobBlendedImage.SaveImage(Path.Combine(baseDir, $"blend_{blob.X}_{blob.Y}.png"));
            
            // 入力画像に矩形描画
            rectImage.DrawRectangle(blob, Color.Red, thickness:12, margin: 16);
        }
        
        // 矩形描画結果を保存
        rectImage.SaveImage(Path.Combine(baseDir, "rect.png"));
    }
}
// resultは必ず最後の行に記述してください
result

最後に

画像の保存には時間がかかる可能性があるため、タクトタイム内に処理が完了するか必ずご確認ください。
検出した画像を残しておきたい場合に利用できますので、ぜひご活用ください!

詳細はスクリプトパラメータのAPI仕様をご確認ください。

今回追加された処理は IMenouImage のメソッドも含まれますので、あわせてご参照ください。

「いいね!」 8