오봉이와 함께하는 개발 블로그
Naver A.I Platform - OCR(텍스트 인식) 본문
728x90
CLOVA OCR (Optical Character Recognition)
- 광학 문자 인식 API 서비스
- 사진 속에서 텍스트 정보를 찾고 의미를 판별하는 기술
- 언어와 이미지 데이터를 입력 받아서, 그에 맞는 인식 결과를 텍스트로 반환
- 결과를 콘솔에 출력
- 텍스트가 포함된 이미지 파일을 전송하고
- JSON 형태의 결과 받아서 콘솔에 출력
- OCRService 클래스 생성
- clovaOCRService() 메소드 추가 : 결과 콘솔에 출력
- jsonToString() 메소드 추가 : 결과로 추출된 텍스트 반환
@Service
public class OCRService {
public void clovaOCRService() {
String apiURL = "";
String secretKey = "";
String imageFile = "/Users/gobyeongchae/Desktop/ocr1.PNG";
String result = "";
try {
URL url = new URL(apiURL);
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setUseCaches(false);
con.setDoInput(true);
con.setDoOutput(true);
con.setReadTimeout(30000);
con.setRequestMethod("POST");
String boundary = "----" + UUID.randomUUID().toString().replaceAll("-", "");
con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
con.setRequestProperty("X-OCR-SECRET", secretKey);
JSONObject json = new JSONObject();
json.put("version", "V2");
json.put("requestId", UUID.randomUUID().toString());
json.put("timestamp", System.currentTimeMillis());
JSONObject image = new JSONObject();
image.put("format", "jpg");
image.put("name", "demo");
JSONArray images = new JSONArray();
images.put(image);
json.put("images", images);
String postParams = json.toString();
con.connect();
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
long start = System.currentTimeMillis();
File file = new File(imageFile);
writeMultiPart(wr, postParams, file, boundary);
wr.close();
int responseCode = con.getResponseCode();
BufferedReader br;
if (responseCode == 200) {
br = new BufferedReader(new InputStreamReader(con.getInputStream()));
} else {
br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
}
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = br.readLine()) != null) {
response.append(inputLine);
}
br.close();
System.out.println(response);
result = jsonToString(response.toString());
System.out.println(result);
} catch (Exception e) {
System.out.println(e);
}
}
private static void writeMultiPart(OutputStream out, String jsonMessage, File file, String boundary) throws
IOException {
StringBuilder sb = new StringBuilder();
sb.append("--").append(boundary).append("\r\n");
sb.append("Content-Disposition:form-data; name=\"message\"\r\n\r\n");
sb.append(jsonMessage);
sb.append("\r\n");
out.write(sb.toString().getBytes("UTF-8"));
out.flush();
if (file != null && file.isFile()) {
out.write(("--" + boundary + "\r\n").getBytes("UTF-8"));
StringBuilder fileString = new StringBuilder();
fileString
.append("Content-Disposition:form-data; name=\"file\"; filename=");
fileString.append("\"" + file.getName() + "\"\r\n");
fileString.append("Content-Type: application/octet-stream\r\n\r\n");
out.write(fileString.toString().getBytes("UTF-8"));
out.flush();
try (FileInputStream fis = new FileInputStream(file)) {
byte[] buffer = new byte[8192];
int count;
while ((count = fis.read(buffer)) != -1) {
out.write(buffer, 0, count);
}
out.write("\r\n".getBytes());
}
out.write(("--" + boundary + "--\r\n").getBytes("UTF-8"));
}
out.flush();
}
public String jsonToString(String jsonResultStr) {
String resultText = "";
// API 호출 결과 받은 JSON 형태 문자열에서 텍스트 추출
// JSONParser 사용하지 않음
// images / 0 / fields / inferText 추출
JSONObject jsonObj = new JSONObject(jsonResultStr);
JSONArray imageArray = (JSONArray) jsonObj.get("images");
if(imageArray != null) {
JSONObject tempObj = (JSONObject) imageArray.get(0);
JSONArray fieldArray = (JSONArray) tempObj.get("fields");
if(fieldArray != null) {
for(int i=0; i<fieldArray.length(); i++) {
tempObj = (JSONObject) fieldArray.get(i);
resultText += (String) tempObj.get("inferText") + " ";
}
}
} else {
System.out.println("없음");
}
return resultText;
}
}
// ocr 페이지 호출
@RequestMapping("/clovaOCR")
public void clovaOCR() {
ocrService.clovaOCRService();
}
- 서비스에서 결과 반환하고 컨트롤러에서 뷰 페이지로 출력
- REST API 방법 : @RestController 사용
- 파일 업로드
- Ajax 사용해서 서버로 전달하고 결과 받아서 현재 페이지에 출력
- APIRestController 클래스 추가 : @RestController
- 서비스 클래스의 메소드 호출하고 결과 받아서 반환
- ocr.js
- Ajax 사용해서 파일 전송하고 결과 받아서 현재 페이지에 출력
@Service
public class OCRService {
public String clovaOCRService(String filePathName) {
String apiURL = "";
String secretKey = "";
String imageFile = filePathName;
String result = "";
try {
URL url = new URL(apiURL);
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setUseCaches(false);
con.setDoInput(true);
con.setDoOutput(true);
con.setReadTimeout(30000);
con.setRequestMethod("POST");
String boundary = "----" + UUID.randomUUID().toString().replaceAll("-", "");
con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
con.setRequestProperty("X-OCR-SECRET", secretKey);
JSONObject json = new JSONObject();
json.put("version", "V2");
json.put("requestId", UUID.randomUUID().toString());
json.put("timestamp", System.currentTimeMillis());
JSONObject image = new JSONObject();
image.put("format", "jpg");
image.put("name", "demo");
JSONArray images = new JSONArray();
images.put(image);
json.put("images", images);
String postParams = json.toString();
con.connect();
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
long start = System.currentTimeMillis();
File file = new File(imageFile);
writeMultiPart(wr, postParams, file, boundary);
wr.close();
int responseCode = con.getResponseCode();
BufferedReader br;
if (responseCode == 200) {
br = new BufferedReader(new InputStreamReader(con.getInputStream()));
} else {
br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
}
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = br.readLine()) != null) {
response.append(inputLine);
}
br.close();
System.out.println(response); // API 호출 결과를 콘솔에 출력
// jsonToString() 메소드 호출하고 결과 받아옴
result = jsonToString(response.toString());
System.out.println(result); // 뭔가가 있는 줄 알았어요
} catch (Exception e) {
System.out.println(e);
}
return result;
}
private static void writeMultiPart(OutputStream out, String jsonMessage, File file, String boundary) throws
IOException {
StringBuilder sb = new StringBuilder();
sb.append("--").append(boundary).append("\r\n");
sb.append("Content-Disposition:form-data; name=\"message\"\r\n\r\n");
sb.append(jsonMessage);
sb.append("\r\n");
out.write(sb.toString().getBytes("UTF-8"));
out.flush();
if (file != null && file.isFile()) {
out.write(("--" + boundary + "\r\n").getBytes("UTF-8"));
StringBuilder fileString = new StringBuilder();
fileString
.append("Content-Disposition:form-data; name=\"file\"; filename=");
fileString.append("\"" + file.getName() + "\"\r\n");
fileString.append("Content-Type: application/octet-stream\r\n\r\n");
out.write(fileString.toString().getBytes("UTF-8"));
out.flush();
try (FileInputStream fis = new FileInputStream(file)) {
byte[] buffer = new byte[8192];
int count;
while ((count = fis.read(buffer)) != -1) {
out.write(buffer, 0, count);
}
out.write("\r\n".getBytes());
}
out.write(("--" + boundary + "--\r\n").getBytes("UTF-8"));
}
out.flush();
}
public String jsonToString(String jsonResultStr) {
String resultText = "";
// API 호출 결과 받은 JSON 형태 문자열에서 텍스트 추출
// JSONParser 사용하지 않음
// images / 0 / fields / inferText 추출
JSONObject jsonObj = new JSONObject(jsonResultStr);
JSONArray imageArray = (JSONArray) jsonObj.get("images");
if(imageArray != null) {
JSONObject tempObj = (JSONObject) imageArray.get(0);
JSONArray fieldArray = (JSONArray) tempObj.get("fields");
if(fieldArray != null) {
for(int i=0; i<fieldArray.length(); i++) {
tempObj = (JSONObject) fieldArray.get(i);
resultText += (String) tempObj.get("inferText") + " ";
}
}
} else {
System.out.println("없음");
}
return resultText;
}
}
@RestController
public class APIRestController {
@Autowired
private OCRService ocrService;
@RequestMapping("/clovaOCR")
public String clovaOCR(@RequestParam("uploadFile") MultipartFile file){
String result = "";
try {
// 1. 파일 저장 경로 설정 : 실제 서비스되는 위치 (프로젝트 외부에 저장)
String uploadPath = "/Users/gobyeongchae/Desktop/productImages";
// 2. 원본 파일 이름 알아오기
String originalFileName = file.getOriginalFilename();
String filePathName = uploadPath + originalFileName;
// 3. 파일 생성
File file1 = new File(filePathName);
// 4. 서버로 전송
file.transferTo(file1);
// 서비스에 파일 path와 파일명 전달 -> 서비스 메소드에서 변경
// 서비스에서 반환된 텍스트를 result에 저장
result = ocrService.clovaOCRService(filePathName);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>OCR</title>
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script src="/js/ocr.js"></script>
</head>
<body>
<!-- 파일 업로드 -->
<h3>OCR : 텍스트 추출</h3>
<form id="ocrForm" enctype="multipart/form-data">
파일 : <input type="file" id="uploadFile" name="uploadFile">
<input type="submit" value="결과 확인">
</form>
<br><br>
<!-- 결과 출력 (텍스트) -->
<h3>OCR : 텍스트 추출 결과</h3>
<div id="resultDiv"></div>
<br><br>
<!-- 이미지 출력 (새로운 방법으로 알려줄 것임) -->
<h3>OCR : 원본 이미지 파일</h3>
<div id="resultImg"></div>
<br><br>
<a href="/">index 페이지로 이동</a>
</body>
</html>
$(function () {
// submit 했을 때 처리
$('#ocrForm').on('submit', function (event) {
event.preventDefault();
var formData = new FormData($('#ocrForm')[0]);
var fileName = $('#uploadFile').val().split("\\").pop();
$.ajax({
type : "post",
enctype : "multipart/form-data",
url : "clovaOCR",
data : formData,
processData : false, // 필수
contentType : false, // 필수
success:function (result) {
$('#resultDiv').text(result);
// 이미지 출력 (div에 append)
$('#resultImg').empty();
$('#resultImg').append('<img src="/images/'+fileName+'"/>');
},
error:function (e) {
alert("오류 발생" + e);
}
});
})
})
728x90
'Naver A.I Platform' 카테고리의 다른 글
Naver A.I Platform - Object Detection (객체 탐지) (0) | 2022.01.25 |
---|---|
Naver A.I Platform - Pose Estimation(포즈 인식) (0) | 2022.01.24 |
Naver A.I Platform - CLOVA Face Recognition(CFR - 얼굴 감지) (0) | 2022.01.22 |
Naver A.I platform - CLOVA Face Recognition (CFR - 유명인 유사도 측정) (0) | 2022.01.22 |
Naver A.I Platform - 개요 (0) | 2022.01.22 |
Comments