がりらぼ

WindowsRuntimeの応援ブログ

MobileServices上でOpenCVsharpを用いて画像処理して返す

Azureに画像をアップロードしたら画像処理をして返してくれる仕組みを作りたかったのでやってみました。

.NetバックエンドでHttpPostでBodyに画像データをbyteで入れて送受信します。

とりあえず.NetバックエンドのプロジェクトでNugetからOpenCV Sharpを入れましょう。

f:id:garicchi:20150305011114p:plain

そんでもってカスタムAPIを追加するためにコントローラーを追加します。

f:id:garicchi:20150305011322p:plain

カスタムコントローラーを選択しましょう。

f:id:garicchi:20150305011333p:plain

できたらPostメソッドをつくります。

public async Task<HttpResponseMessage> Post()
{
    byte[] buff = await Request.Content.ReadAsByteArrayAsync();
    byte[] resultBuff=null;

    var response = new HttpResponseMessage();
    try
    {
        using (IplImage sourceImage = IplImage.FromImageData(buff, LoadMode.Unchanged))
        {
            using (IplImage resultImage = Cv.CreateImage(new CvSize(sourceImage.Width, sourceImage.Height), BitDepth.U8, 1))
            {
                // replace here!
                Cv.CvtColor(sourceImage, resultImage, ColorConversion.BgrToGray);


                resultBuff = resultImage.ToBytes(".jpg");
            }

        }

        response.StatusCode = HttpStatusCode.OK;
        response.Content = new ByteArrayContent(resultBuff);
    }
    catch (Exception e)
    {
        response.StatusCode = HttpStatusCode.BadRequest;
        response.Content = new StringContent(e.Message);
    }
                
    return response;
    
}

リクエストはBody内に入ってるByteArrayContentを受け取ります。
そしてIplImageに変換してそれをグレースケールに変換します。

変換したIplImageはToBytesメソッドでjpgのbyte配列に変換してHttpResponseMessageで返します。
例外が発生したときはとりあえずBadRequestで返します。

ではWindowsストアアプリからアクセスするサンプルはこんな感じになります。

private async void btnCapture_Click(object sender, RoutedEventArgs e)
{
    CameraCaptureUI capture = new CameraCaptureUI();
    capture.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Jpeg;
    var file = await capture.CaptureFileAsync(CameraCaptureUIMode.Photo);

    IRandomAccessStream stream = await file.OpenReadAsync();
    byte[] buff = new byte[stream.Size];
    DataReader reader = new DataReader(stream);
    await reader.LoadAsync((uint)stream.Size);
    reader.ReadBytes(buff);
    
    HttpClient client = new HttpClient();
    var message = await client.PostAsync("{mobile service url}/api/Image",new ByteArrayContent(buff));
    byte[] resultImage = await message.Content.ReadAsByteArrayAsync();

    BitmapImage bitmapImage = new BitmapImage();
    
    MemoryStream mStream = new MemoryStream(resultImage);
    await bitmapImage.SetSourceAsync(mStream.AsRandomAccessStream());

   
    image.Source = bitmapImage;



}

CameraCaptureUIでキャプチャしたjpg画像をHttpClientから送信します。
レスポンスは処理後の画像が帰ってくるはずなのでBitmapImageに変換してImageコントロールのSorceプロパティに入れます。

f:id:garicchi:20150305012312p:plain

MobileServicesの.NetバックエンドはASP.net WebAPIなので独自サーバーのIIS上でも同じことができます。

これでOpenCVが動かないプラットフォーム上でも画像を送信するだけでMobileServices上で処理して返してくれるのでサイコーな感じになります。