はじめに
前回の記事の続きになります。
今回は、前回作成したモデルにRESTで画像データを送信し、予測結果の取得を行う。
headerとbodyに設定する値を確認
CustomVisionのポータルから、Peformanceタブを選択。
Prediction URLを押下する。
※この際、作成したモデルが(compact)となっていると、Prediction URLが非活性となる。
その場合はprojectSettingからDomainsを変更して、再度モデル作成を行う。
表示されたURLとKeyを控える。
画像をURLで送信する場合は、上のパラメータ、
画像をファイルとして送信する場合、下のパラメータを使用する。
postmanを使用してPOST通信のテスト
実装を行う前に先ほどのURLとKeyで正しく結果を受け取ることが出来るか、postmanを利用してテストを行う。
bodyに判別したい画像データを選択する。
画像データはバイナリ化して送信するため、binaryを選択する。
無事に判定結果を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アプリを作ってみたい。