LoginSignup
1
0

More than 1 year has passed since last update.

CustomVisionからRESTで予測結果を取得

Last updated at Posted at 2023-02-03

はじめに

前回の記事の続きになります。

今回は、前回作成したモデルにRESTで画像データを送信し、予測結果の取得を行う。

headerとbodyに設定する値を確認

CustomVisionのポータルから、Peformanceタブを選択。
Prediction URLを押下する。
image.png

※この際、作成したモデルが(compact)となっていると、Prediction URLが非活性となる。
 その場合はprojectSettingからDomainsを変更して、再度モデル作成を行う。
image.png

表示されたURLとKeyを控える。
画像をURLで送信する場合は、上のパラメータ、
画像をファイルとして送信する場合、下のパラメータを使用する。
image.png

postmanを使用してPOST通信のテスト

実装を行う前に先ほどのURLとKeyで正しく結果を受け取ることが出来るか、postmanを利用してテストを行う。

headerに先ほど控えたURLとKeyを入力
image.png

bodyに判別したい画像データを選択する。
画像データはバイナリ化して送信するため、binaryを選択する。
image.png

今回送信する画像はこちら
1927158799.jpg

Sendボタンを押下すると・・・
image.png

無事に判定結果をJson形式で受け取る事が出来た。

JavaでPost通信の実行

まずは、受け取るJsonの形式に合わせてEntityクラスを作成する。

package wansearch.test;

import java.util.List;

public class ResponseData {
	
	private String id;
	private String project;
	private String iteration;
	private String created;
	private List<ProbabilityData> predictions;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getProject() {
		return project;
	}

	public void setProject(String project) {
		this.project = project;
	}

	public String getIteration() {
		return iteration;
	}

	public void setIteration(String iteration) {
		this.iteration = iteration;
	}

	public String getCreated() {
		return created;
	}

	public void setCreated(String created) {
		this.created = created;
	}

	public List<ProbabilityData> getPredictions() {
		return predictions;
	}

	public void setPredictions(List<ProbabilityData> predictions) {
		this.predictions = predictions;
	}
}

先ほど、postmanで確認した通り、responseのjsonは二重構造となっているため、それにあわせてフィールドを定義する。

package wansearch.test;

public class ProbabilityData {

	private double probability;
	private String tagId;
	private String tagName;
	
	public double getProbability() {
		return probability;
	}

	public void setProbability(double probability) {
		this.probability = probability;
	}

	public String getTagId() {
		return tagId;
	}

	public void setTagId(String tagId) {
		this.tagId = tagId;
	}

	public String getTagName() {
		return tagName;
	}

	public void setTagName(String tagName) {
		this.tagName = tagName;
	}
}

あとは、POST通信を行いEntityに結果を格納するだけ。
JsonをJavaオブジェクトに変換するため、Jacksonを使用。

(こちらを参考にさせて頂きました。)
https://itsakura.com/java-jackson

package wansearch.test;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.HttpClientBuilder;

import com.fasterxml.jackson.databind.ObjectMapper;


public class postTest {

	public static void main(String[] args) throws IOException {

		// 画像ファイルを読み込む
		byte[] byteVal = new byte[1];
		FileInputStream fileInputStream = new FileInputStream("C:\\25741389603.jpg");	
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		
		// 画像ファイルをバイナリ化
		while (fileInputStream.read(byteVal) > 0) {
			byteArrayOutputStream.write(byteVal);
		}
		fileInputStream.close();
		byteArrayOutputStream.close();
		byteVal = byteArrayOutputStream.toByteArray();


		// CustomVisionで指定されたHeaderを設定
		HttpClient client = HttpClientBuilder.create().build();
		HttpPost httpPost = new HttpPost("先ほど控えたURLを記載");
		httpPost.addHeader("Content-Typet", "application/octet-stream");
		httpPost.addHeader("Prediction-Key", "先ほど控えたKeyを記載");
		
		// バイナリ化した画像データをBodyに設定
		ByteArrayEntity entity = new ByteArrayEntity(byteVal, ContentType.create("image/jpeg"));
		httpPost.setEntity(entity);

		// Post通信を実施
		HttpResponse response = client.execute(httpPost);

		// responseを受け取りStringに変換
		BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
		StringBuilder sb = new StringBuilder();
		sb.append(br.readLine());
		
		ObjectMapper mapper = new ObjectMapper();
		ResponseData responseData  = mapper.readValue(sb.toString(), ResponseData.class);
		
		// 結果を表示
		for (ProbabilityData resultData : responseData.getPredictions()) {
			System.out.println(resultData.getTagName() + ":" + resultData.getProbability());
		}

		br.close();

	}
}

柴犬:0.87166977
ビーグル:0.043759253
フレンチ・ブルドック:0.03192451
パグ:0.024318052
ボーダー・コリー:0.0050128275
シーズー:0.00455389
シベリアン・ハスキー:0.0041088113
ドーベルマン:0.0034000375
ミニチュア・ピンシャー:0.0022857597
ポメラニアン:0.0021645236
シュナウザー:0.0016360354
パピヨン:0.0015117836
プードル:0.001046774
コリー:5.681897E-4
ミニチュア・プードル:5.6106586E-4
トイプードル:4.977784E-4
ヨークシャー・テリア:4.6511774E-4
ミニチュア・シュナウザー:3.5254107E-4
マルチーズ:1.6327013E-4

一部桁落ちしてるけど、無事結果を受け取る事が出来た。
柴ちゃんの次候補してビーグルと判定されているのが面白い。

まとめ

想像以上に、手軽に結果が取れた。
次回はこれを使って、簡単なWebアプリを作ってみたい。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0