오봉이와 함께하는 개발 블로그
Naver A.I platform - CLOVA Face Recognition (CFR - 유명인 유사도 측정) 본문
Naver A.I Platform
Naver A.I platform - CLOVA Face Recognition (CFR - 유명인 유사도 측정)
오봉봉이 2022. 1. 22. 23:08728x90
CLOVA Face Recognition (CFR) 실습 (유명인 유사도 측정)
- 스프링 부트 프로젝트 생성
- JSON dependency 추가
- json-simple
- json
- CelebrityVO 생성
- CFRCelebrityService 클래스 추가
- clovaFaceRecogCel() 메소드 추가
- API Java 코드 복사해서 붙여넣기
- clovaFaceRecogCel() 메소드 추가
- APIController에 추가
- celebrityView.jsp 생성
- index.jsp에 추가
- 콘솔에 JSON 형태의 결과 출력 확인
- JSON 데이터 추출
- 결과로 받은 JSON 형식의 문자열에서 value와 confidence추출해서 CelebrityVO에 저장
- CFRCelebrityService 클래스에 메소드로 추가
- jsonToVo(String jsonResultStr)
- 결과로 받은 JSON 문자열을 전달 받아, value와 confidence추출
- CelebrityVO에 저장한 후 리스트(ArrayList)에 추가
- CelebrityVO 리스트 반환
- jsonToVoList(String jsonResultStr) 메소드 추가로 인한 변경 사항
- clovaFaceRecogCel() 메소드에서 jsonToVoList() 호출하는 코드 추가
- 서비스에서 컨트롤러에게 반환하기 위해 clovaFaceRecogCel() 메소드의 반환형 변경 및 return 값 추가
- 컨트롤러에서는 서비스 호출하고 결과 받는 코드로 변경하고 Model 추가
- celebrityView.jsp에 출력 부분 추가
- jsonToVo(String jsonResultStr)
public class CelebrityVO {
private String value;
private double confidence;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public double getConfidence() {
return confidence;
}
public void setConfidence(double confidence) {
this.confidence = confidence;
}
}
@Controller
public class APIController {
@Autowired
private CFRCelebrityService cfrserviceCel;
@RequestMapping("/")
public String index() {
return "index";
}
@RequestMapping("/faceRecogCel")
public String faceRecogCel() {
cfrserviceCel.clovaFaceRecogCel();
return "celebrityView";
}
}
package com.ai.ex.naver_ai_platform.service;
import com.ai.ex.naver_ai_platform.model.CelebrityVO;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.springframework.stereotype.Service;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
@Service
public class CFRCelebrityService {
public ArrayList<CelebrityVO> clovaFaceRecogCel(String filePathName) {
//StringBuffer reqStr = new StringBuffer();
String clientId = "";//애플리케이션 클라이언트 아이디값";
String clientSecret = "";//애플리케이션 클라이언트 시크릿값";
ArrayList<CelebrityVO> celList = new ArrayList<CelebrityVO>();
try {
String paramName = "image"; // 파라미터명은 image로 지정
// String imgFile = "C:/ai/song.jpg"; // 전송할 이미지 파일
String imgFile = filePathName;
File uploadFile = new File(imgFile);
String apiURL = "https://naveropenapi.apigw.ntruss.com/vision/v1/celebrity"; // 유명인 얼굴 인식
URL url = new URL(apiURL);
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setUseCaches(false);
con.setDoOutput(true);
con.setDoInput(true);
// multipart request
String boundary = "---" + System.currentTimeMillis() + "---";
con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
con.setRequestProperty("X-NCP-APIGW-API-KEY-ID", clientId);
con.setRequestProperty("X-NCP-APIGW-API-KEY", clientSecret);
OutputStream outputStream = con.getOutputStream();
PrintWriter writer = new PrintWriter(new OutputStreamWriter(outputStream, "UTF-8"), true);
String LINE_FEED = "\r\n";
// file 추가
String fileName = uploadFile.getName();
writer.append("--" + boundary).append(LINE_FEED);
writer.append("Content-Disposition: form-data; name=\"" + paramName + "\"; filename=\"" + fileName + "\"").append(LINE_FEED);
writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(fileName)).append(LINE_FEED);
writer.append(LINE_FEED);
writer.flush();
FileInputStream inputStream = new FileInputStream(uploadFile);
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
inputStream.close();
writer.append(LINE_FEED).flush();
writer.append("--" + boundary + "--").append(LINE_FEED);
writer.close();
BufferedReader br = null;
int responseCode = con.getResponseCode();
if(responseCode==200) { // 정상 호출
br = new BufferedReader(new InputStreamReader(con.getInputStream()));
} else { // 오류 발생
System.out.println("error!!!!!!! responseCode= " + responseCode);
br = new BufferedReader(new InputStreamReader(con.getInputStream()));
}
String inputLine;
if(br != null) {
StringBuffer response = new StringBuffer();
while ((inputLine = br.readLine()) != null) {
response.append(inputLine);
}
br.close();
System.out.println(response.toString()); // 서버로부터 받은 결과를 콘솔에 출력 (JSON 형태)
// jsonToVoList() 메소드 호출하면서 결과 json 문자열 전달
celList = jsonToVoList(response.toString());
} else {
System.out.println("error !!!");
}
} catch (Exception e) {
System.out.println(e);
}
// CelebrityVO 리스트 반환
return celList;
}
// API 서버로부터 받은 JSON 형태의 결과 데이터를 전달받아서 value와 confidence 추출하고
// VO 리스트 만들어 반환하는 함수
public ArrayList<CelebrityVO> jsonToVoList(String jsonResultStr){
ArrayList<CelebrityVO> celList = new ArrayList<CelebrityVO>();
try {
//JSON 형태의 문자열에서 JSON 오브젝트 "faces" 추출해서 JSONArray에 저장
JSONParser jsonParser = new JSONParser();
JSONObject jsonObj = (JSONObject) jsonParser.parse(jsonResultStr);
JSONArray celebrityArray = (JSONArray) jsonObj.get("faces");
// JSONArray의 각 요소에서 value와 confidence 추출하여
// CelebrityVO 담아 리스트에 추가
if(celebrityArray != null) {
// value와 confidence 추출
// JSONArray 각 요소에서 value와 confidence 추출
for(int i=0; i < celebrityArray.size(); i++){
JSONObject tempObj = (JSONObject) celebrityArray.get(i);
tempObj = (JSONObject) tempObj.get("celebrity");
String value = (String) tempObj.get("value");
double confidence = (double) tempObj.get("confidence");
// VO에 저장해서 리스트에 추가
CelebrityVO vo = new CelebrityVO();
vo.setValue(value);
vo.setConfidence(confidence);
celList.add(vo);
}
} else {
//유명인을 찾지 못한 경우 ("faces" : [])
CelebrityVO vo = new CelebrityVO();
vo.setValue("없음");
vo.setConfidence(0);
}
} catch (Exception e) {
e.printStackTrace();
}
return celList;
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>결과</title>
</head>
<body>
<h1>인식 결과</h1>
<a href="/">인덱스 이동</a>
</body>
</html>
- 첨부 파일로 변경
- 현재 코드에서 파일명을 직접 적었는데, 파일을 서버에 올리는 기능 추가
- 서버의 특정 폴더에 이미지 저장
- 외부 폴더 지정
- 결과 페이지에서 서버로 올린 이미지 출력
- celebrityView.jsp에 파일 업로드 부분 추가
- 컨트롤러에 추가
public class CelebrityVO {
private String value;
private double confidence;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public double getConfidence() {
return confidence;
}
public void setConfidence(double confidence) {
this.confidence = confidence;
}
}
@Controller
public class APIController {
@Autowired
private CFRCelebrityService cfrServiceCel;
// index 페이지로 이동
@RequestMapping("/")
public String index() {
return "index";
}
@RequestMapping("/faceRecogCelForm")
public String faceRecogCelForm() {
return "celebrityView";
}
// (1) 유명인 얼굴인식 API 호출 : 결과를 콘솔에 출력
// 변경 ->
// (2) 유명인 얼굴인식 API 호출 결과 CelebrityVO 리스트 받아서 Model에 담아 celebrityView.jsp 뷰 페이지로 전달
@RequestMapping("/faceRecogCel")
public String faceRecogCel(@RequestParam("uploadFile") MultipartFile file,
Model model) throws IOException {
// 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);
ArrayList<CelebrityVO> celList = new ArrayList<CelebrityVO>();
// 서비스에 파일 path와 파일명 전달 -> 서비스 메소드에서 변경
// 서비스에서 반환된 CelebrityVO 리스트 저장
celList = cfrServiceCel.clovaFaceRecogCel(filePathName);
//Model에 "celList" 이름으로 저장 -> view 페이지로 전달
model.addAttribute("celList", celList);
model.addAttribute("fileName", originalFileName);
return "celebrityView";
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>유명인 얼굴 인식</title>
</head>
<body>
<!-- 서버로 파일 전송 -->
<h3>유명인 얼굴 인식</h3>
<form id="celebrityForm" method="post" action="<c:url value='/faceRecogCel'/>" enctype="multipart/form-data">
파일 : <input type="file" id="uploadFile" name="uploadFile">
<input type="submit" value="결과 확인">
</form>
<hr>
<c:if test="${not empty celList }">
<h3>유명인 얼굴 인식 결과</h3>
<table border="1" width="400">
<tr><th>유명인</th><th>정확도</th></tr>
<c:forEach items="${celList}" var="cel">
<tr>
<td>${cel.value }</td>
<td><fmt:formatNumber value="${cel.confidence }" pattern="0.0000" /></td>
</tr>
</c:forEach>
</table>
</c:if>
<br><br>
<c:if test="${not empty fileName }">
<img src="<c:url value='/images/${fileName}' />">
</c:if>
<br><br>
<a href="/">index 페이지로 이동</a>
</body>
</html>
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 - OCR(텍스트 인식) (6) | 2022.01.24 |
Naver A.I Platform - CLOVA Face Recognition(CFR - 얼굴 감지) (0) | 2022.01.22 |
Naver A.I Platform - 개요 (0) | 2022.01.22 |
Comments