본문 바로가기
Framework & Library/Spring Framework

[Spring Framework] : 딥러닝 (이미지 인식)

by 오주현 2021. 10. 27.
반응형
딥러닝

지도 학습은 문제지랑 답을 준다고 생각하면 되고 강화 학습은 문제지를 주고 스스로 답을 찾게 한다고 보면 됩니다.

여기서 머신 러닝은 지도 학습이라 볼 수 있고 딥러닝은 비지도학습, 강화학습이라고 볼 수 있습니다.

 

이미지 인식을 위한 딥러닝 플랫폼이 여러가지가 있습니다.

1. 구글에서 만든 텐서플로우

2. 인텔에서 만든 OpenCV

3. HP에서 만든 Tesseract

 

Tesseract를 이용한 이미지 인식

- 요즘은 수학적 알고리즘 보다는 학습된 데이터를 통해 이미지를 인식 시킵니다. 그러다보니 학습된 데이터 량을 늘리기 위해 빅데이터를 활용합니다.

- 학습을 위해 공개된 데이터를 활용해 실습을 하면 좋습니다.

 

데이터 학습 방법

- 제공하는 전용 툴을 통해 학습 시킵니다.

- 파이썬으로 프로그래밍하여 학습합니다.

 

파이썬으로 학습하는 이유

- 언어 사용이 단순하고 강력합니다.

- 학습은 처리 성능을 고려하지 않고 프로그램 실행해도 되기 때문입니다.

- 학습용 데이터를 만들 때 가장 많이 사용됩니다.

 

코드 아래 설명을 달기가 애매해서 주석으로 넣어뒀습니다.

주석을 확인하면서 코드를 확인하면 됩니다.


	<!-- OCR 구현을 위한 Tesseract4 라이브러리 다운로드 -->
	<dependency>
	<groupId>net.sourceforge.tess4j</groupId>
	<artifactId>tess4j</artifactId>
	<version>4.4.1</version>
	</dependency>

pom.xml

- 테서렉트를 사용하기 위해 라이브러리를 다운로드 받아 줍니다.


package poly.dto;

public class OcrDTO {

	private String filePath; //저장된 이미지 파일의 파일 저장 경로
	private String fileName; // 저장된 이미지 파일 이름
	private String textFromImage; // 저장된 이미지로부터 읽은 글씨
	public String getFilePath() {
		return filePath;
	}
	public void setFilePath(String filePath) {
		this.filePath = filePath;
	}
	public String getFileName() {
		return fileName;
	}
	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
	public String getTextFromImage() {
		return textFromImage;
	}
	public void setTextFromImage(String textFromImage) {
		this.textFromImage = textFromImage;
	}
	
	
}

DTO


package poly.util;

import java.io.File;

public class FileUtil {

	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;
	}
}

FileUtil

 


package poly.service;

import poly.dto.OcrDTO;

public interface IOcrService {

	OcrDTO getReadforImageText(OcrDTO pDTO) throws Exception;
}

IService

 


package poly.service.impl;

import java.io.File;

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.service.IOcrService;
import poly.util.CmmUtil;

@Service("OcrService")
public class OcrService implements IOcrService {
	
	private Logger log = Logger.getLogger(this.getClass());
	
	// 이미지 파일로부터 문자 읽어 오기

	@Override
	public OcrDTO getReadforImageText(OcrDTO pDTO) throws Exception {
		
		log.info(this.getClass().getName() + ".getFoodInfoFromWEB start !");
		
		File imageFile = new File(CmmUtil.nvl(pDTO.getFilePath()) + "//" + CmmUtil.nvl(pDTO.getFileName()));
		
		//Ocr 기술 사용을 위한 테서렉트 플랫폼 객체 생성
		ITesseract instance = new Tesseract();
		
		// OCR 분석에 필요한 기준 데이터, 저장 경로는 물리 경로를 사용한다.
		instance.setDatapath("C:\\tess-data");
		
		instance.setLanguage("eng");
		
		// 이미지 파일로부터 텍스트 읽기
		String result = instance.doOCR(imageFile);
		
		// 읽은 글자를 DTO에 저장하기
		pDTO.setTextFromImage(result);
		
		log.info("result : " + result);
		
		log.info(this.getClass().getName() + ".getFoodInfoFromWEB start !");
		
		return pDTO;
	}

}

Service


package poly.util;

import java.io.File;

public class FileUtil {

	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;
	}
}

FileUtil


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("OcrController")
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";
	
	@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.setFileName(saveFileName);//저장되는 파일명
			pDTO.setFilePath(saveFilePath);//저장되는 경로
			
			OcrDTO rDTO = ocrService.getReadforImageText(pDTO);
			
			if(rDTO == null) {
				rDTO = new OcrDTO();
			}
			
			res = CmmUtil.nvl(rDTO.getTextFromImage());
		}
		
		//크롤링 결과를 넣어주기
		model.addAttribute("res", res);
		
		log.info(this.getClass().getName() + ".getReadforImageText end !");
		
		return "/ocr/TextFromImage";
	}
}

controller


<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>이미지로부터 텍스트 인식을 위한 파일 업로드 페이지</title>
</head>
<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>

ImageFileUpload.jsp


<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
 <%@ page import = "poly.util.CmmUtil" %>
 <% 
 //컨트롤러부터 전달 받은 데이터
 String res = CmmUtil.nvl((String) request.getAttribute("res"));
 %>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>이미지로부터 텍스트 인식 결과</title>
</head>
<body>
<h2>이미지 인식 결과</h2>
<hr/>
이미지로부터 텍스트 인식 결과는 <%=res %> 입니다.
</body>
</html>

TextFromImage.jsp


 

반응형

댓글