- 이미지인식을 윈한 딥러닝 기술
- 개요
- 딥러닝은 기본적으로 학습된 데이터 필요함
- 이미 학습되어 있는 데이터를 가지고 실습을 진행함
- 제공하는 툴을 활용하는데 파이썬이 언어 사용법이 단순하며, 강력한 기능들을 제공하고 처리 성능을 고려하지 않고, 프로그램 실행해도 되기 때문
- OCR 구현을 위한 Tesseract4 라이브러리 다운로드
- <dependency> <groupId>net.sourceforge.tess4j</groupId> <artifactId>tess4j</artifactId> <version>4.4.1</version> </dependency>
- DTO
package poly.dto;
public class OcrDTO {
private String seq; //순번
private String save_file_name; // 저장된 이미지 파일 이름
private String save_file_path; // 저장된 이미지 파일의 파일 저장 경로
private String org_file_name; //원래 파일명
private String ext; //파일확장자
private String ocr_text; // 저장된 이미지로부터 읽은 글씨
private String reg_id; //최초등록자
private String reg_dt; //최초등록일
private String chg_id; //최근수정자
private String chg_dt; //최근수정일
public String getSeq() {
return seq;
}
public void setSeq(String seq) {
this.seq = seq;
}
public String getSave_file_name() {
return save_file_name;
}
public void setSave_file_name(String save_file_name) {
this.save_file_name = save_file_name;
}
public String getSave_file_path() {
return save_file_path;
}
public void setSave_file_path(String save_file_path) {
this.save_file_path = save_file_path;
}
public String getOrg_file_name() {
return org_file_name;
}
public void setOrg_file_name(String org_file_name) {
this.org_file_name = org_file_name;
}
public String getExt() {
return ext;
}
public void setExt(String ext) {
this.ext = ext;
}
public String getOcr_text() {
return ocr_text;
}
public void setOcr_text(String ocr_text) {
this.ocr_text = ocr_text;
}
public String getReg_id() {
return reg_id;
}
public void setReg_id(String reg_id) {
this.reg_id = reg_id;
}
public String getReg_dt() {
return reg_dt;
}
public void setReg_dt(String reg_dt) {
this.reg_dt = reg_dt;
}
public String getChg_id() {
return chg_id;
}
public void setChg_id(String chg_id) {
this.chg_id = chg_id;
}
public String getChg_dt() {
return chg_dt;
}
public void setChg_dt(String chg_dt) {
this.chg_dt = chg_dt;
}
}
package poly.service;
import poly.dto.OcrDTO;
public interface IOcrService {
OcrDTO getReadforImageText(OcrDTO pDTO) throws Exception;
}
package poly.service.impl;
import java.io.File;
import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import poly.dto.OcrDTO;
import poly.persistance.mapper.IOcrMapper;
import poly.service.IOcrService;
import poly.util.CmmUtil;
@Service("OcrService")
public class OcrService implements IOcrService {
@Resource(name="OcrMapper")
private IOcrMapper ocrMapper;
// 로그 파일 생성 및 로그 출력을 위한 log4j 프레임워크의 자바 객체
private Logger log = Logger.getLogger(this.getClass());
/**
* 이미지 파일로부터 문자 읽어 오기
*
* @param pDTO 이미지 파일 정보
* @return pDTO 이미지로부터 읽은 문자열
*/
@Override
public OcrDTO getReadforImageText(OcrDTO pDTO) throws Exception {
log.info(this.getClass().getName() + ".getReadforImageText start!");
File imageFile = new File(CmmUtil.nvl(pDTO.getSave_file_path()) + "//" + CmmUtil.nvl(pDTO.getSave_file_name()));
log.info(CmmUtil.nvl(pDTO.getSave_file_path()) + "//" + CmmUtil.nvl(pDTO.getSave_file_name()));
// OCR 기술 사용을 위한 Tesseract 플랫폼 객체 생성
ITesseract instance = new Tesseract();
// OCR 분석에 필요한 기준 데이터(이미 각 나라의 언어별로 학습시킨 데이터 위치 폴더)
// 저장 경로는 물리경로를 사용함(전체 경로)
instance.setDatapath("C:\\\\tess-data");
// 한국어 학습 데이터 선택(기본 값은 영어)
//instance.setLanguage("kor"); //한국어 설정
instance.setLanguage("eng"); //영어 설정
// 이미지 파일로부터 텍스트 읽기
String result = instance.doOCR(imageFile);
// 읽은 글자를 DTO에 저장하기
pDTO.setOcr_text(result);
log.info("result : " + result);
log.info(this.getClass().getName() + ".getReadforImageText End!");
ocrMapper.InsertOcrInfo(pDTO);
return pDTO;
}
}
- 년월일 별로 폴더를 생성하는 공통기능 Util
package poly.util;
import java.io.File;
public class FileUtil {
/*
* 현재 날짜를 기준으로 년 / 월 / 일 폴더 생성하기
*
* @param 파일이 저장되는 ROOT폴더
* @return 파일이 저장되기 위해 생성된 전체 폴더 경로
*/
public static String mkdirForDate(String uploadDir) {
String path = uploadDir + DateUtil.getDateTime("/yyyy/MM//dd");
File Folder = new File(path);
if(!Folder.exists()) { // 폴더가 없을경우
Folder.mkdirs(); //폴더를 생성합니다
}
return path;
}
}
package poly.controller;
import java.io.File;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import poly.dto.OcrDTO;
import poly.service.IOcrService;
import poly.util.CmmUtil;
import poly.util.DateUtil;
import poly.util.FileUtil;
/*
* Controller 선언해야만 Spring 프레임워크에서 Controller인지 인식 가능
* 자바 서블릿 역할 수행
* */
@Controller
public class OcrController {
private Logger log = Logger.getLogger(this.getClass());
/*
* 비즈니스 로직(중요 로직을 수행하기 위해 사용되는 서비스를 메모리에 적재(싱글톤패턴 적용됨)
*/
@Resource(name = "OcrService")
private IOcrService ocrService;
// 업로드되는 파일이 저장되는 기본 폴더 설정(자바에서 경로는 /로 표현함)
final private String FILE_UPLOAD_SAVE_PATH = "C:/upload"; // C:\\\\upload 폴더에 저장
/**
* 이미지 인식을 위한 파일업로드 화면 호출
*/
@RequestMapping(value="ocr/imageFileUpload")
public String Index() {
log.info(this.getClass().getName() + ".imageFileUpload!");
return "/ocr/ImageFileUpload";
}
/**
* 파일업로드 및 이미지 인식
*/
@RequestMapping(value = "ocr/getReadforImageText")
public String getReadforImageText(HttpServletRequest request, HttpServletResponse response, ModelMap model,
@RequestParam(value = "fileUpload") MultipartFile mf) throws Exception {
log.info(this.getClass().getName() + ".getReadforImageText start!");
// OCR 실행 결과
String res = "";
// 업로드하는 실제 파일명
// 다운로드 기능 구현시, 임의로 정의된 파일명을 원래대로 만들어주기 위한 목적
String originalFileName = mf.getOriginalFilename();
// 파일 확장자 가져오기
String ext = originalFileName.substring(originalFileName.lastIndexOf(".") + 1, originalFileName.length()).toLowerCase();
// 이미지 파일만 실행되도록 함
if (ext.equals("jpeg") || ext.equals("jpg") || ext.equals("gif") || ext.equals("png")) {
// 웹서버에 저장되는 파일 이름
// 업로드하는 파일 이름에 한글, 특수 문자들이 저장될 수 있기 때문에 강제로 영어와 숫자로 구성된 파일명으로 변경해서 저장한다.
// 리눅스나 유닉스 등 운영체제는 다국어 지원에 취약하기 때문이다.
String saveFileName = DateUtil.getDateTime("24hhmmss") + "." + ext;
// 웹서버에 업로드한 파일 저장하는 물리적 경로
String saveFilePath = FileUtil.mkdirForDate(FILE_UPLOAD_SAVE_PATH);
String fullFileInfo = saveFilePath + "/"+ saveFileName;
// 정상적으로 값이 생성되었는지 로그 찍어서 확인
log.info("ext : " + ext);
log.info("saveFileName : " + saveFileName);
log.info("saveFilePath : " + saveFilePath);
log.info("fullFileInfo : " + fullFileInfo);
// 업로드 되는 파일을 서버에 저장
mf.transferTo(new File(fullFileInfo));
OcrDTO pDTO = new OcrDTO();
pDTO.setSave_file_name(saveFileName); // 저장되는 파일명
pDTO.setSave_file_path(saveFilePath); // 저장되는 경로
pDTO.setExt(ext); // 확장자명
pDTO.setReg_id("admin"); // 등록자
pDTO.setOrg_file_name(originalFileName);
OcrDTO rDTO = ocrService.getReadforImageText(pDTO);
if (rDTO == null) {
rDTO = new OcrDTO();
}
res = CmmUtil.nvl(rDTO.getOcr_text());
rDTO = null;
pDTO = null;
}else {
res = "이미지 파일이 아니라서 인식이 불가능합니다.";
}
// 크롤링 결과를 넣어주기
model.addAttribute("res", res);
log.info(this.getClass().getName() + ".getReadforImageText end!");
return "/ocr/TextFromImage";
}
}
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>이미지로부터 텍스트 인식을 위한 파일 업로드 페이지</title>
<body>
<h2>이미지 인식</h2>
<hr/>
<form name="form1" method="post" enctype="multipart/form-data" action="/ocr/getReadforImageText.do">
<br />
이미지 파일 업로드 : <input type="file" name="fileUpload" />
<br />
<br />
<input type="submit" value="전송" />
</form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<%@ page import="poly.util.CmmUtil"%>
<%
//Controller로부터 전달받은 데이터
String res = CmmUtil.nvl((String) request.getAttribute("res"));
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>이미지로부터 텍스트 인식 결과</title>
<body>
<h2>이미지 인식 결과</h2>
<hr />
이미지로부터 텍스트 인식 결과는 <%=res%> 입니다.
</body>
</html>
댓글