본문 바로가기
프로그래밍언어/Java

[JAVA] OCR 기본활용

by Yikanghee 2021. 12. 29.
  • 이미지인식을 윈한 딥러닝 기술
    • 텐서플로우
      • 구글
    • OpenCV
      • 인텔
    • Tesseract
      • HP
  • 개요
    • 딥러닝은 기본적으로 학습된 데이터 필요함
    • 이미 학습되어 있는 데이터를 가지고 실습을 진행함
    • 제공하는 툴을 활용하는데 파이썬이 언어 사용법이 단순하며, 강력한 기능들을 제공하고 처리 성능을 고려하지 않고, 프로그램 실행해도 되기 때문
  • 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";
   }

}
  • View 이미지업로드 파일 설정
<%@ 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>
  • View 결과
<%@ 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>

'프로그래밍언어 > Java' 카테고리의 다른 글

스프링 웹 방식  (0) 2022.01.11
[JAVA] 객체 생성과 파괴  (0) 2022.01.06
SPRING MVC모델 게시판  (0) 2021.11.22
SPRING MVC모델 Overriding 활용  (0) 2021.11.11
[Java] Array 개념  (0) 2021.07.12

댓글