VISION Rest API 오류 문의

비전 api를 java 환경에서 사용 시 400 에러가 발생합니다…
이유를 모르겠습니다…

파라미터 boxes 타입이 array 인데… 문자열 타입을 사용해서 그런걸까요…

package team3.common.web;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class KakaoTest2 {

private static final Logger logger = LoggerFactory.getLogger(KakaoTest2.class);

public static void main(String[] args) throws IOException {
	File file = new File("d:\\test.jpeg");
	String boxes = "{\"result\":{\"boxes\":[[[97,665],[527,665],[527,682],[97,682]],[[470,612],[570,612],[570,632],[470,632]],[[655,607],[730,607],[730,635],[655,635]],[[207,300],[295,300],[295,390],[207,390]],[[312,290],[572,290],[572,390],[312,390]],[[320,195],[525,195],[525,270],[320,270]],[[220,100],[355,100],[355,170],[220,170]],[[372,97],[588,100],[587,175],[371,172]]]}}";
	
	new KakaoTest2().getTexts(file, boxes);
	
}

public String getTexts(File file, String boxes) throws IOException {

    if (file.length() == 0)
        return null;

    String accessToken = "76b669372178a6e9477834019c31bbb9";
    String CRLF = "\r\n";
    String TWO_HYPHENS = "--";
    String BOUNDARY = "---------------------------012345678901234567890123456";
    HttpsURLConnection conn = null;
    DataOutputStream dos = null;
    FileInputStream fis = null;
    

    int bytesRead, bytesAvailable, bufferSize;
    byte[] buffer;
    int maxBufferSize = 1 * 1024 * 1024;

    // Request
    try {
        URL url = new URL("https://kapi.kakao.com/v1/vision/text/recognize?boxes=" + boxes) ;
        conn = (HttpsURLConnection) url.openConnection();
        conn.setDoInput(true);
        conn.setDoOutput(true);
        conn.setUseCaches(false);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Connection", "Keep-Alive");
        conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDARY);
        conn.setRequestProperty("Authorization", "KakaoAK " + accessToken);
        conn.setRequestProperty("Cache-Control", "no-cache");

        dos = new DataOutputStream(conn.getOutputStream());

    	logger.debug("file : {}", file.getName());
    	
        dos.writeBytes(TWO_HYPHENS + BOUNDARY + CRLF);
        dos.writeBytes("Content-Disposition: form-data; name=\"file\";" + " filename=\"" + file.getName() + "\"" + CRLF);
        dos.writeBytes(CRLF);
        
        fis = new FileInputStream(file);
        bytesAvailable = fis.available();
        bufferSize = Math.min(bytesAvailable, maxBufferSize);
        buffer = new byte[bufferSize];
        bytesRead = fis.read(buffer, 0, bufferSize);
        while (bytesRead > 0) {
            dos.write(buffer, 0, bufferSize);
            bytesAvailable = fis.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            bytesRead = fis.read(buffer, 0, bufferSize);
        }
        dos.writeBytes(CRLF);

        // finish delimiter
        dos.writeBytes(TWO_HYPHENS + BOUNDARY + TWO_HYPHENS + CRLF);

        fis.close();
        dos.flush();
        dos.close();

    } catch (MalformedURLException ex) {
        ex.printStackTrace();
    } catch (IOException ioe) {
        ioe.printStackTrace();
    } finally {
        if (dos != null) try { dos.close(); } catch (IOException ignore) {}
        if (fis != null) try { fis.close(); } catch (IOException ignore) {} }

    // Response
    InputStream inputStream = null;
    BufferedReader reader = null;
    try {
        inputStream = new BufferedInputStream(conn.getInputStream());
        reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        String line;
        StringBuilder builder = new StringBuilder();
        while ((line = reader.readLine()) != null) {
            builder.append(line).append("\n");
        }
        reader.close();
        return builder.toString();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (reader != null) {
            try { reader.close(); } catch (IOException ignore) {}
        }
        if (inputStream != null) {
            try { inputStream.close(); } catch (IOException ignore) {}
        }
        conn.disconnect();
    }
    logger.debug("responseCode : {}", conn.getResponseCode());
    logger.debug("responseMessage : {}", conn.getResponseMessage());

    return null;
}

}

오류코드입니다.

stdout2 16:50:44.819 [main] DEBUG team3.common.web.KakaoTest1 -
file : test.jpeg
stdout2 16:50:45.074 [main] DEBUG team3.common.web.KakaoTest1 -
res : {“result”:{“boxes”:[[[97,665],[527,665],[527,682],[97,682]],[[470,612],[570,612],[570,632],[470,632]],[[655,607],[730,607],[730,635],[655,635]],[[207,300],[295,300],[295,390],[207,390]],[[312,290],[572,290],[572,390],[312,390]],[[320,195],[525,195],[525,270],[320,270]],[[220,100],[355,100],[355,170],[220,170]],[[372,97],[588,100],[587,175],[371,172]]]}}

stdout2 16:50:45.096 [main] DEBUG team3.common.web.KakaoTest1 -
json : {“result”:{“boxes”:[[[97,665],[527,665],[527,682],[97,682]],[[470,612],[570,612],[570,632],[470,632]],[[655,607],[730,607],[730,635],[655,635]],[[207,300],[295,300],[295,390],[207,390]],[[312,290],[572,290],[572,390],[312,390]],[[320,195],[525,195],[525,270],[320,270]],[[220,100],[355,100],[355,170],[220,170]],[[372,97],[588,100],[587,175],[371,172]]]}}
stdout2 16:50:45.104 [main] DEBUG team3.common.web.KakaoTest2 -
file : test.jpeg
java.io.IOException: Server returned HTTP response code: 400 for URL: https://kapi.kakao.com/v1/vision/text/recognize?boxes={“result”:{“boxes”:[[[97,665],[527,665],[527,682],[97,682]],[[470,612],[570,612],[570,632],[470,632]],[[655,607],[730,607],[730,635],[655,635]],[[207,300],[295,300],[295,390],[207,390]],[[312,290],[572,290],[572,390],[312,390]],[[320,195],[525,195],[525,270],[320,270]],[[220,100],[355,100],[355,170],[220,170]],[[372,97],[588,100],[587,175],[371,172]]]}}
stdout2 16:50:45.125 [main] DEBUG team3.common.web.KakaoTest2 -
responseCode : 400
stdout2 16:50:45.125 [main] DEBUG team3.common.web.KakaoTest2 -
responseMessage : Bad Request
stdout2 16:50:45.125 [main] DEBUG team3.common.web.KakaoTest1 -
result : null
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1876)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at team3.common.web.KakaoTest2.getTexts(KakaoTest2.java:105)
at team3.common.web.KakaoTest1.main(KakaoTest1.java:41)

팁)
프로그램으로 얻은 이미지나 어떠한 사유로 인해, 문자의 위치정보가 항상 같다면, Text Detection API 없이 바로 알고 있는 좌표를 이용해 Text Recognition API를 사용하실 수 있습니다.

응용)
이미지에서 인식하길 원하는 문자 영역의 BOX가 특정 위치에 있는 경우, Detection에서 얻은 좌표를 이용해 필터링한 뒤, BOX 개수를 줄여서 Recognition API를 호출하면 더 빠른 속도로 결과를 얻을 수 있습니다.

위 팁과 응용의 기능을 이용하고자 합니다.
특정한 좌표를 파라미터로 넣어주는 방법을 모르겠습니다.

@jhhhhh93
boxes 파람은 박스좌표 리스트입니다.

https://kapi.kakao.com/v1/vision/text/recognize?boxes=[[[97,665],[527,665],[527,682],[97,682]],[[470,612],[570,612],[570,632],[470,632]],[[655,607],[730,607],[730,635],[655,635]],[[207,300],[295,300],[295,390],[207,390]],[[312,290],[572,290],[572,390],[312,390]],[[320,195],[525,195],[525,270],[320,270]],[[220,100],[355,100],[355,170],[220,170]],[[372,97],[588,100],[587,175],[371,172]]]

이런식으로 호출하셔야해요.

https://developers.kakao.com/docs/restapi/vision#문자-영역-감지 API의 응답 json에서 result 하위에 boxes value만 추출하여 사용하시면 됩니다.