본문 바로가기

OpenCV없는 컬러영상처리 및 마우스 이벤트

컬러 영상처리 전처리부

 

컬러이미지는 웹서버를 거쳐야 화면에 출력될수 있다.

 

 

 

 

 

<!DOCTYPE html>
<html>
	<head>
        <meta charset="UTF-8">
	<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"); // 물감, 붓이 들은 통
                inCtx.beginPath();
                inCtx.fillStyle="white"
                inCtx.rect(30,30,490,490);
                inCtx.fill();
                inCtx.font="20px Gothic"
                inCtx.fillStyle="black"
                inCtx.fillText("inImage 사진",215,275);
                outCanvas = document.getElementById("outCanvas"); // 도화지
                outCtx = outCanvas.getContext("2d"); // 물감, 붓이 들은 통
                outCtx.beginPath();
                outCtx.fillStyle="white"
                outCtx.rect(30,30,490,490);
                outCtx.fill();
                outCtx.font="20px Gothic"
                outCtx.fillStyle="black"
                outCtx.fillText("outImage 사진",215,275);
        }

        function openImage() {
            //inFile = document.getElementById("inFile").files[0]; // 선택한 RAW 파일(LENNA512.RAW)
            var fileNum=document.getElementById('fileNum').value;//"55","5"
            if(parseInt(fileNum)<10)
                fileNum="0"+fileNum;//"05"
            else
                fileNum=fileNum;
            
            var inFname="Nature99(Small)/picture"+fileNum+".jpg";//Nature99(Small)/picture05.jpg
            //그림 파일 --> 이미지 객체
            var imageObject = new Image();//빈이미지객체생성
            imageObject.src=inFname;//파일이 이미지 객체에 쏙 들어감.

            imageObject.onload=function() {
                //중요! 입력영상 크기 알아내기
                inH = imageObject.height;
                inW = imageObject.width;
                // 도화기 크기를 이미지 크기로 조절
                inCanvas.height = inH;
                inCanvas.width = inW;
                //이미지 객체-->캔버스(화면)
                inCtx.drawImage(imageObject,0,0,inW,inH);
                //Image Object에서 화면에 출력 했고 이제 RAM으로 이동해야함

                //메모리 할당(3차원 배열)
                inImage = new Array(3);//3면 4차원 배열로 하면 투명도 까지 해볼수 있다.
                for(var m=0;m<3;m++){
                    inImage[m] = new Array(inH);
                     for(let n=0; n<inH; n++)
                        inImage[m][n] = new Array(inW);
                }
                //--중요!--캔버스의 이미지(화면) --> 배열의 칼라로 추출
                var colorBlob = inCtx.getImageData(0,0,inW,inH);//원하는 부분 만큼만 뽑아올수 있다.
                var R,G,B,Alpha;//Alpha는 투명도 값
                //이미지를 뽑아옴 2차원배열로 가자!!
                for(var i=0;i<inH;i++){
                    for(var k=0;k<inW;k++){
                        var pos = (i*inW + k)*4;//1픽셀 == 4byte
                        R = colorBlob.data[pos+0];
                        G = colorBlob.data[pos+1];
                        B = colorBlob.data[pos+2];
                        Alpha = colorBlob.data[pos+3];
                        inImage[0][i][k]=R;
                        inImage[1][i][k]=G;
                        inImage[2][i][k]=B;
                        //inImage[3][i][k]=Alpha;//alpha는 안 쓰니까 생략
                    }
                }



            }
        }
        function displayImage() {
            // 도화기 크기를 이미지 크기로 조절
            outCanvas.height = outH;
            outCanvas.width = outW;

            outPaper= outCtx.createImageData(outW, outH); // 이미지 크기의 빈 종이를 준비
            //W와 H를 잘구별해줘야하는데 테스트하고 바꾸는게 나음 굳이 기억ㄴㄴ

            for (let i=0; i<outH; i++) {
                for (let k=0; k<outW; k++) {
                    let R = outImage[0][i][k];  
                    let G = outImage[1][i][k];  
                    let B = outImage[2][i][k];  
                         
                    outPaper.data[(i*outW + k)*4 + 0] = R; // Red
                    outPaper.data[(i*outW + k)*4 + 1] = G; // Green
                    outPaper.data[(i*outW + k)*4 + 2] = B; // Blue
                    outPaper.data[(i*outW + k)*4 + 3] = 255; // Alpha (투명도)
                }
            }
            outCtx.putImageData(outPaper,0,0);
        }
        let algoNum;
        function selectAlgorithm(selNum) {
            algoNum = parseInt(selNum.value);
            switch (algoNum) {
                    case 101://동일영상
                        equalImage();break;
                    case 102://반전영상
                        reverseImage_mouse();break;
                    case 103://영상더하기
                        lightImage_mouse();break;
                    case 104://영상빼기
                        darkImage_mouse();break;
                    case 105://영상곱하기
                        gopImage_mouse();break;
                    case 106://영상나누기
                        divImage_mouse();break;
                    case 107://흑백127기준
                        bwImage_mouse();break;
                    case 108://흑백평균기준
                        avgImage_mouse();break;
                    case 109://흑백중앙값기준
                        bwMiddleImage();break;
                    case 110://파라볼라 캡
                        paraCapImage_mouse();break;
                    case 111://파라볼라 컵
                        paraCupImage_mouse();break;
                    case 112://감마
                        gammaImage_mouse();break;
                    case 113://그레이스케일
                        grayImage_mouse();break;
                    case 114://채도 변환
                        saturImage_mouse();break;
                    case 115://명도 변환
                        intensityImage_mouse();break;
                    case 116://오렌지추출(컴퓨터비전)
                        orangeImage_mouse();break;


                    case 201:// 상하미러링
                        udImage_mouse();break;
                    case 202:// 좌우미러링
                        lrImage_mouse();break;
                    case 203:// 영상이동
                        swapImage_mouse();break;
                    case 204:// 영상회전
                        rotateImage_mouse();break;
                    case 205:// 영상회전 90도
                        image90_mouse();break;
                    case 206:// 영상축소
                        zoomOutImage_mouse();break;
                    case 207:// 영상확대
                        zoomInImage_mouse();break;
                    case 208:// 영상확대(백워딩)
                        zoomInImage2();break;
                    case 209:// 반시계회전
                        spinImage_mouse();break;

                    
                    case 301:// 엠보싱
                        embossImage_mouse();break;
                    case 302:// 블러링
                        blurrImage_mouse();break;
                    case 303:// 샤프닝
                        sharpenImage_mouse();break;
                    case 304:// 가우시안
                        gaussianImage_mouse();break;
                    case 305:// 고주파 샤프닝
                        hpfSharpImage_mouse();break;
                    case 306:// 저주파 통과 샤프닝
                        OnLpfImage_mouse();break;
                    case 307:// 에지 검출 이동과 차분
                        sadImage_mouse();break;
                    case 308:// 유사연산자
                        opImage_mouse();break;
                    case 309: //로버츠 알고리즘
                        robertsImage_mouse();break;
                    case 310: //소벨 알고리즘
                        sobelImage_mouse();break;
                    case 311: //프리윗 알고리즘
                        prewittImage_mouse();break;
                    case 312: //라플라시안 알고리즘
                        laplacianImage_mouse();break;
                    case 313: //로그 알고리즘
                        logImage_mouse();break;
                    case 314: //dog 알고리즘
                        dogImage_mouse();break;
                    case 315: //모자이크
                        mosaic_mouse();break;


                    case 401:// 스트레칭
                        stretchImage_mouse();break;
                    case 402:// 엔드-인
                        endInImage_mouse();break;
                    case 403:// 평활화
                        equalizeImage_mouse();break;
            }
        }
        ////////////////////////////////////////////////
        //이벤트리스너
        ///////////////////////////////////////////////
        let startX, startY, endX, endY;
        let pressYN = false;
        let imageData;//마우스 클릭 시점의 화면
        ///////마우스 처리 공통함수 --> //////////////
            function __downMouse(event){
                startX = event.offsetX;
                startY = event.offsetY;
                pressYN=true;
                //현재 상태를 보관하기
                imageData = inCtx.getImageData(0,0,inCanvas.width, inCanvas.height);

                //alert(startX+","+startY);
            }
            function __upMouse(event){  
                inCtx.putImageData(imageData,0,0);
                endX = event.offsetX;
                endY = event.offsetY;

                //선택한 네모박스 안쪽만 영상처리 되기
                //시작과 끝을 재배치
                if(startX > endX){
                    let tmp = startX;
                    startX = endX;
                    endX = tmp;
                }
                if(startY > endY){
                    let tmp = startY;
                    startY = endY;
                    endY = tmp;
                }
                
                    //마우스 이벤트 리스너 끄기
                    inCanvas.removeEventListener("mousedown",__downMouse,false);
                    inCanvas.removeEventListener("mouseup",__upMouse,false);
                    inCanvas.removeEventListener("mousemove",__moveMouse,false);
                    pressYN= false;
                
                switch (algoNum) {
                    case 101://동일영상
                        equalImage();break;
                    case 102://반전영상
                        reverseImage();break;
                    case 103://영상더하기
                        lightImage();break;
                    case 104://영상빼기
                        darkImage();break;
                    case 105://영상곱하기
                        gopImage();break;
                    case 106://영상나누기
                        divImage();break;
                    case 107://흑백127기준
                        bwImage();break;
                    case 108://흑백평균기준
                        avgImage();break;
                    case 110://파라볼라 캡
                        paraCapImage();break;
                    case 111://파라볼라 컵
                        paraCupImage();break;
                    case 112://감마
                        gammaImage();break;
                    case 113://그레이스케일
                        grayImage();break;
                    case 114://채도 변환
                        saturImage();break;
                    case 115://명도 변환
                        intensityImage();break;
                    case 116://오렌지추출(컴퓨터비전)
                        orangeImage();break;

                    case 201:// 상하미러링
                        udImage();break;
                    case 202:// 좌우미러링
                        lrImage();break;
                    case 203:// 영상이동
                        swapImage();break;
                    case 204:// 영상회전
                        rotateImage();break;
                    case 205:// 영상회전 90도
                        image90();break;
                    case 206:// 영상축소
                        zoomOutImage();break;
                    case 207:// 영상확대
                        zoomInImage();break;
                    case 208:// 영상확대(백워딩)
                        zoomInImage2();break;
                    case 209:// 반시계회전
                        spinImage();break;

                    case 301:// 엠보싱
                        embossImage();break;
                    case 302:// 블러링
                        blurrImage();break;
                    case 303:// 샤프닝
                        sharpenImage();break;
                    case 304:// 가우시안
                        gaussianImage();break;
                    case 305:// 고주파 샤프닝
                        hpfSharpImage();break;
                    case 306:// 저주파 통과 샤프닝
                        OnLpfImage();break;
                    case 307:// 에지 검출 이동과 차분
                        sadImage();break;
                    case 308:// 유사연산자
                        opImage();break;
                    case 309: //로버츠 알고리즘
                        robertsImage();break;
                    case 310: //소벨 알고리즘
                        sobelImage();break;
                    case 311: //프리윗 알고리즘
                        prewittImage();break;
                    case 312: //라플라시안 알고리즘
                        laplacianImage();break;
                    case 313: //로그 알고리즘
                        logImage();break;
                    case 314: //dog 알고리즘
                        dogImage();break;
                    case 315: //모자이크
                        mosaic();break;

                    case 401:// 스트레칭
                        stretchImage();break;
                    case 402:// 엔드-인
                        endInImage();break;
                    case 403:// 평활화
                        equalizeImage();break;
              
            }
                //alert(startX+","+startY);
                pressYN=false;
            }
            function __moveMouse(event){
                if(!pressYN)
                    return;
                
                inCtx.putImageData(imageData,0,0);

                endX = event.offsetX;
                endY = event.offsetY;

                inCtx.beginPath();//선그리기 시작
                inCtx.strokeStyle = 'blue';
                inCtx.lineWidth =1;

                inCtx.rect(startX, startY, (endX-startX),(endY-startY));
                
                inCtx.stroke();
                inCtx.closePath();
                
            }

        ////////<--마우스 처리 공통함수 //////////////////
        function onEventListener(){
            inCanvas.addEventListener("mousedown",__downMouse,false);
            inCanvas.addEventListener("mouseup",__upMouse,false);
            inCanvas.addEventListener("mousemove",__moveMouse,false);
        }

//////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
////////////////////////
/////RGB --> HSV변환함수
////////////////////////
        function rgb2hsv(r, g, b) {//RGB --> HSV변환함수
            var max = Math.max(r, g, b), min = Math.min(r, g, b),
                d = max - min,
                h,
                s = (max === 0 ? 0 : d / max),
                v = max / 255;

            switch (max) {
                case min: h = 0; break;
                case r: h = (g - b) + d * (g < b ? 6: 0); h /= 6 * d; break;
                case g: h = (b - r) + d * 2; h /= 6 * d; break;
                case b: h = (r - g) + d * 4; h /= 6 * d; break;
            }
            return {
                h: h,    s: s,    v: v
            };
        }

        function hsv2rgb(h, s, v) {//HSV-->RGB 변환함수
            var r, g, b, i, f, p, q, t;

            h = h*360;  s = s*100;    v = v*100;

            h = Math.max(0, Math.min(360, h));
            s = Math.max(0, Math.min(100, s));
            v = Math.max(0, Math.min(100, v));
            
            h /= 360;   s /= 100;     v /= 100;

            i = Math.floor(h * 6);
            f = h * 6 - i;
            p = v * (1 - s);
            q = v * (1 - f * s);
            t = v * (1 - (1 - f) * s);
            switch (i % 6) {
                case 0: r = v, g = t, b = p; break;
                case 1: r = q, g = v, b = p; break;
                case 2: r = p, g = v, b = t; break;
                case 3: r = p, g = q, b = v; break;
                case 4: r = t, g = p, b = v; break;
                case 5: r = v, g = p, b = q; break;
            }
            return {
                r: Math.round(r * 255),
                g: Math.round(g * 255),
                b: Math.round(b * 255)
            };
    }
    
    </script>
    <style>
        .abc{
            padding: 50px;
        }
    </style>
	</head>
	
	<body onload="init()" class = "abc">
        <center>
            <h1>칼라 영상 처리 (Beta 7)</h1>
            <table>
            <form>
            <tr>
                <td> <input type="checkbox" id="mouseEnable">사각형 선택<input type="number" id="fileNum">
                    <input type="button" id="inFile" value="이미지 열기" onclick="openImage()"><br></td>
                <td><select name="pixel" onchange="selectAlgorithm(this.form.pixel)">
                <ul>
                    <li><option value="0">*화소점 처리*</option>
                    <li><option value="101">동일 영상</option>
                    <li><option value="102">영상 반전</option>
                    <li><option value="103">영상 더하기</option>
                    <li><option value="104">영상 빼기</option>
                    <li><option value="105">영상 곱하기</option>
                    <li><option value="106">영상 나누기</option>
                    <li><option value="107">흑백127기준</option>
                    <li><option value="108">흑백평균기준</option>
                    <li><option value="109">흑백중앙값기준</option>
                    <li><option value="110">파라볼라 캡</option>
                    <li><option value="111">파라볼라 컵</option>
                    <li><option value="112">감마</option>
                    <li><option value="113">그레이스케일</option>
                    <li><option value="114">채도 변환</option>
                    <li><option value="115">명도 변환</option>
                    <li><option value="116">오렌지 추출(컴퓨터 비전)</option>
                </ul>
            </select>
            <select name="geometry" onchange="selectAlgorithm(this.form.geometry)">
                <ul>
                    <li><option value="0">*기하학 처리*</option>
                    <li><option value="201">상하 미러링</option>
                    <li><option value="202">좌우 미러링</option>
                    <li><option value="203">영상 이동</option>
                    <li><option value="204">영상 회전</option>
                    <li><option value="205">영상 회전 90도</option>
                    <li><option value="206">영상 축소</option>
                    <li><option value="207">영상 확대</option>
                    <li><option value="208">영상 확대(백워딩)</option>
                    <li><option value="209">반시계 회전</option>
                </ul>  
            </select>
            <select name="area" onchange="selectAlgorithm(this.form.area)">
                <ul>
                    <li><option value="0">*화소영역 처리*</option>
                    <li><option value="301">엠보싱</option>
                    <li><option value="302">블러링</option>
                    <li><option value="303">샤프닝</option>
                    <li><option value="304">가우시안</option>
                    <li><option value="305">고주파 샤프닝</option>
                     <li><option value="306">저주파통과 고주파</option>
                    <li><option value="307">이동과 차분</option>
                    <li><option value="308">유사연산자</option>
                    <li><option value="309">로버츠마스크 수평/수직</option>
                    <li><option value="310">소벨마스크 수평/수직</option>
                    <li><option value="311">프리윗마스크 수평/수직</option>
                    <li><option value="312">라플라시안</option>
                    <li><option value="313">로그</option>
                    <li><option value="314">도그</option>
                    <li><option value="315">모자이크</option>
                </ul> 
            </select>
            <select name="histo" onchange="selectAlgorithm(this.form.histo)">
                <ul>
                    <li><option value="0">*히스토그램 처리*</option>
                    <li><option value="401">스트레칭</option>
                    <li><option value="402">엔드-인</option>
                    <li><option value="403">평활화</option>
                </ul>
            </select></td>
            </form></tr>
            
            <tr><br></tr>
            <tr><br></tr><tr><br></tr><tr><br></tr>
            <tr>
            <td><canvas  id="inCanvas"  style="background-color:rgb(253, 206, 119)"
                width="550" height="550"></canvas></td>
                
            <td><canvas  id="outCanvas"  style="background-color:rgb(179, 160, 223)"
                width="550" height="550"></canvas></td></tr>
            </table>
        </center>     
	</body>
</html>

'OpenCV없는 컬러영상처리 및 마우스 이벤트' 카테고리의 다른 글

마우스 이벤트를 통한 칼라영상처리  (0) 2022.09.25
히스토그램 처리하기  (0) 2022.09.23
화소 영역 처리  (0) 2022.09.23
기하학처리  (0) 2022.09.23
화소점처리  (0) 2022.09.23