영상 처리 프로그래밍 - 전처리부

이효정·2022년 9월 19일
post-thumbnail
<!DOCTYPE html>
<html>
	<head>
    <title>영상처리</title> 
    <link rel="stylesheet" type="text/css" href="style.css"/>
	<script>
        //////////////
        // 전역 변수부
        //////////////
        let inCanvas, inCtx, inPaper; // 입력 영상 관련
        let outCanvas, outCtx, outPaper; // 출력 영상 관련
        let inImage, inH, inW; // 2차원배열, 높이, 폭
        let outImage, outH, outW; // 2차원배열, 높이, 폭
        let inFile;

        //////////////
        // 공통 함수부 :  Open(), Display().....
        //////////////
        function init() {
            inCanvas = document.getElementById("inCanvas"); // 도화지
            inCtx = inCanvas.getContext("2d"); // 물감, 붓이 들은 통
            outCanvas = document.getElementById("outCanvas"); // 도화지
            outCtx = outCanvas.getContext("2d"); // 물감, 붓이 들은 통
        }

        function openImage() {
            inFile = document.getElementById("inFile").files[0]; // 선택한 RAW 파일(LENNA512.RAW)
            // (중요!) 선택한 이미지의 크기를 확인
            inH = inW = Math.sqrt(inFile.size); // 128, 256, 512, 1024.....
            // 이미지 크기의 메모리(2차원배열)를 확보
            inImage = new Array(inH);
            for(let i=0; i<inH; i++)
                inImage[i] = new Array(inW);
            // 파일  --> 메모리
            let reader = new FileReader();
            reader.readAsBinaryString(inFile);
            reader.onload = function () {
                let blob = reader.result; // 파일을 한 덩어리(blob)으로 가져옴.
                // 덩어리(blob)에서 한점한점 뽑아서, 배열에 넣기... 몇번 반복? 512x512
                for (let i=0; i<inH; i++) {
                    for (let k=0; k<inW; k++) {
                        let sPixel = (i*inH + k); // 시작 위치
                        let ePixel = (i*inH + k) + 1; // 끝 위치
                        inImage[i][k] = blob.slice(sPixel,ePixel).charCodeAt(0); // 0~1까지 뽑아라. 0만 뽑힘.  //'뙓' -->  223
                    }
                }
                // 도화지 크기를 이미지 크기로 조절
                inCanvas.height = inH;
                inCanvas.width = inW;
                // ** 입력 메모리(inImage)를 페이퍼에 콕콕 찍어서 출력한 후,  페이퍼를 캔버스에 떡 붙이기.
                inPaper= inCtx.createImageData(inH, inW); // 이미지 크기의 빈 종이를 준비
                for (let i=0; i<inH; i++) {
                    for (let k=0; k<inW; k++) {
                        let px = inImage[i][k];
                        inPaper.data[(i*inH + k)*4 + 0] = px; // Red
                        inPaper.data[(i*inH + k)*4 + 1] = px; // Green
                        inPaper.data[(i*inH + k)*4 + 2] = px; // Blue
                        inPaper.data[(i*inH + k)*4 + 3] = 255; // Alpha (투명도)
                    }
                }
                inCtx.putImageData(inPaper,0,0);
            }
        }
        function displayImage() {
            // 도화지 크기를 이미지 크기로 조절
            outCanvas.height = outH;
            outCanvas.width = outW;

            outPaper= outCtx.createImageData(outH, outW); // 이미지 크기의 빈 종이를 준비
            for (let i=0; i<outH; i++) {
                for (let k=0; k<outW; k++) {
                    let px = outImage[i][k];  
                    outPaper.data[(i*outH + k)*4 + 0] = px; // Red
                    outPaper.data[(i*outH + k)*4 + 1] = px; // Green
                    outPaper.data[(i*outH + k)*4 + 2] = px; // Blue
                    outPaper.data[(i*outH + k)*4 + 3] = 255; // Alpha (투명도)
                }
            }
            outCtx.putImageData(outPaper,0,0);
        }

        function selectAlgorithm(selNum) {
            switch (parseInt(selNum.value)) {
                case 101 : // 동일영상
                    equalImage();   break;
                case 102 : // 반전 영상
                    reverseImage(); break;
                case 103 : // 밝게하기
                    addImage(); break;
                case 104 : // 어둡게하기
                    subImage(); break;
                case 105 : // 곱하기
                    mulImage(); break;
                case 106 : // 나누기
                    divImage(); break;
                case 107 : // 흑백(127기준)
                    black127Image(); break;
                case 108 : // 흑백(평균기준)
                    blackAvgImage(); break;
                case 109 : // 파라볼라(캡)
                    pbCapImage(); break;
                case 110 : // 파라볼라(캡)
                    pbCupImage(); break;
                case 111 : // 감마
                    gammaImage(); break;
             
                case 201 : // 상하 미러링
                    upDownImage(); break;
                case 202 : // 좌우 미러링
                    leftRightImage(); break;
                case 203 : // 축소하기
                    zoomOutImage(); break;
                case 204 : // 확대하기
                    zoomInImage(); break;
                case 205 : // 이동하기
                    moveImage(); break;
                case 206 : // 회전하기
                    rotate1Image(); break;
                case 207 : // 회전하기(원본크기 유지)
                    rotate2Image(); break;

                case 301 : // 엠보싱
                    embossImage(); break;
                case 302 : // 블러링
                    blurrImage(); break;
                case 303 : // 가우시안 필터
                    gaussianImage(); break;
                case 304 : // 샤프닝
                    sharpeningImage(); break;
                case 305 : // 고주파 필터 샤프닝
                    highSharpeningImage(); break;
                case 306 : // 저주파 필터 샤프닝
                    lowSharpeningImage(); break;
                case 307 : // 경계선 검출
                    boundaryImage(); break;
                case 308 : // 유사 연산자
                    homogenImage(); break;
                case 309 : // 차 연산자
                    differenceImage(); break;
                case 310 : // LoG
                    LoGImage(); break;
                case 311 : // DoG
                    DoGImage(); break;
                case 312 : // 라플라시안
                    laplacianImage(); break;
                case 313 : // 로버츠 마스크
                    robertsImage(); break;
                case 314 : // 소벨 마스크
                    sobelImage(); break;
                case 315 : // 프리윗 마스크
                    prewittImage(); break;

                case 401 : // 히스토그램 스트래칭
                    stretchImage(); break;
                case 402 : // 엔드-인 탐색
                    endInImage(); break;
                case 403 : // 히스토그램 평활화
                    equalizeImage(); break;
            }
        }
        </script>
    </head>
    
    <body onload="init()" class="edit">
        <div class="head">Photo Editor</div><br>
        <center><form>
            <div class="filebox"> <label for="inFile">파일 선택</label>
            <input type="file" id="inFile" onchange="openImage()"/></div> <br><br>
            <div class="selectbox"><select name='pixel' onchange = "selectAlgorithm(this.form.pixel)">
                <option value="0"> 화소점 처리 </option>
                <optgroup>
                    <option value=101> 동일 영상 </option>
                    <option value=102> 영상 반전 </option>
                    <option value=103> 밝게하기 </option>
                    <option value=104> 어둡게하기 </option>
                    <option value=105> 곱하기 </option>
                    <option value=106> 나누기 </option>
                    <option value=107> 흑백(127기준) </option>
                    <option value=108> 흑백(평균기준) </option>
                    <option value=109> 파라볼라(캡) </option>
                    <option value=110> 파라볼라(컵) </option>
                    <option value=111> 감마 </option>
                </optgroup>
                </select>
            <select name="geometry" onchange = "selectAlgorithm(this.form.geometry)">
                <option value="0"> 기하학 처리 </option>
                <optgroup>
                <option value="201"> 상하 미러링 </option>
                <option value="202"> 좌우 미러링 </option>
                <option value="203"> 축소하기 </option>
                <option value="204"> 확대하기 </option>
                <option value="205"> 이동하기 </option>
                <option value="206"> 회전하기 </option>
                <option value="207"> 회전하기(원본크기) </option>
                </optgroup>
            </select>
                <select name="area" onchange = "selectAlgorithm(this.form.area)">
                    <option value="0"> 화소영역 처리 </option>
                    <optgroup>
                    <option value="301"> 엠보싱 </option>
                    <option value="302"> 블러링 </option>
                    <option value="303"> 가우시안 필터 </option>
                    <option value="304"> 샤프닝 </option>
                    <option value="305"> 고주파 필터 샤프닝 </option> 
                    <option value="306"> 저주파 필터 샤프닝 </option> 
                    <option value="307"> 경계선검출 </option>
                    <option value="308"> 유사 연산자 </option>
                    <option value="309"> 차 연산자 </option>
                    <option value="310"> LoG </option>
                    <option value="311"> DoG </option>
                    <option value="312"> 라플라시안 </option>
                    <option value="313"> 로버츠 </option>
                    <option value="314"> 소벨 </option>
                    <option value="315"> 프리윗 </option>
                    </optgroup>
                </select>
                 <select name="histo" onchange = "selectAlgorithm(this.form.histo)">
                        <option value="0"> 히스토그램 처리 </option>
                        <optgroup>
                        <option value="401"> 스트래칭 </option>
                        <option value="402"> 앤드-인 </option>
                        <option value="403"> 평활화 </option>
                        </optgroup>
                        </select></div>
        </form>
        <table border="1">
           <th>Before</th>
            <th>After</th>
            <tr><td>
            <canvas  id="inCanvas"  style="background-color:lightblue"></canvas>
            </td><td>  
            <canvas id="outCanvas"  style="background-color:lightsteelblue"></canvas>
        </center>
        </body>
    </html>

0개의 댓글