코딩 연습장/Javascript

자바스크립트를 이용한 개인 프로젝트 - 11(영상 처리 알고리즘)

Do아 2021. 6. 16. 09:42
728x90

2021/04/01(목)

 

 

 

 

유사연산자/라플라시안 알고리즘 참고

https://cordingdoah.tistory.com/93

 

자바스크립트를 이용한 개인 프로젝트 - 10(영상 처리 알고리즘)

2021/04/01(목) 샤프닝/가우시안/고주파샤프닝 알고리즘 참고 https://cordingdoah.tistory.com/92 자바스크립트를 이용한 개인 프로젝트 - 9(영상 처리 알고리즘) 2021/04/01(목) 엠보싱/블러링 알고리즘 참고 ht.

cordingdoah.tistory.com

 

 

 

 

영상처리 알고리즘 : 히스토그램 스트레칭, 히스토그램 엔드인, 히스토그램 평활화 구현하기

바로 고!!




- 히스토그램 스트레칭

명암 비를 향상시키는 연산으로, 낮은 명암 대비를 보이는 영상의 화질을 향상시키는 방법

 


<히스토그램 스트레칭>

        //히스토그램 스트레칭 
        function histoStrech() {

            clickEventDown();
            var low = outImageArray[0][0].charCodeAt(0);
            var high = outImageArray[0][0].charCodeAt(0);

            for (var i = 0; i < outHeight; i++)
                for (var k = 0; k < outWidth; k++) {
                    pixel = outImageArray[i][k].charCodeAt(0);

                    if (pixel < low)
                        low = pixel;
                    else if (pixel > high)
                        high = pixel;
                }

            for (var i = 0; i < outHeight; i++)
                for (var k = 0; k < outWidth; k++) {
                    valueOfInImage = outImageArray[i][k].charCodeAt(0);
                    formula = (valueOfInImage - low) / (high - low) * 255;

                    outImageArray[i][k] = String.fromCharCode(formula);
                }

            displayImage();
            clickEvent();
        }

 

1. 가장 낮은 명도와 가장 높은 명도를 찾기위해 low, high 변수 선언하고 배열 첫번째로 초기화

2. 전체 배열에서 가장낮은 명도, 가장 높은 명도를 구하기 위한 이중 포문

3. 히스토그램 스트레칭 공식에 따라 기존 배열 값 - low / high - low * 255를 해주고 다시 삽입

4. 배열 출력 메소드 

 

 

 

 

--> 히스토그램 스트레칭 결과화면

별로 차이가 안나보이지만 좀 더 선명해지는 것을 볼 수 있음

 

 

 

 

<히스토그램 엔드인>

        //히스토그램 엔드인
        function histoEndInSearch() {

            clickEventDown();
            var low = outImageArray[0][0].charCodeAt(0);
            var high = outImageArray[0][0].charCodeAt(0);

            for (var i = 0; i < outHeight; i++)
                for (var k = 0; k < outWidth; k++) {
                    pixel = outImageArray[i][k].charCodeAt(0);

                    if (pixel < low)
                        low = pixel;
                    else if (pixel > high)
                        high = pixel;
                }

            low += 50;
            high -= 50;
            for (var i = 0; i < outHeight; i++)
                for (var k = 0; k < outWidth; k++) {
                    valueOfInImage = outImageArray[i][k].charCodeAt(0);
                    formula = (valueOfInImage - low) / (high - low) * 255;

                    if (formula > 255)
                        formula = 255;
                    else if (formula < 0)
                        formula = 0;

                    outImageArray[i][k] = String.fromCharCode(formula);
                }

            displayImage();
            clickEvent();
        }

1. 가장 낮은 명도와 가장 높은 명도를 찾기위해 low, high 변수 선언하고 배열 첫번째로 초기화

2. 전체 배열에서 가장낮은 명도, 가장 높은 명도를 구하기 위한 이중 포문

3. 가장 낮은 명도에 50을 더하고 가장 높은 명도에 50을 빼서 격차를 조금 줄여줌

4. 히스토리 스트레칭 연산을 사용하고 그 값이 0에서 255 사이의 값인지 확인하고 삽입

5. 출력 메소드 호출

 

 

 

 

--> 히스토그램 엔드인 결과화면

 

명암대비가 더 진해진 것을 알 수 있음

 

 

 

 

- 히스토그램 평활화

어둡게 촬영된 영상의 히스토그램을 조절하여 명암 분포가 빈약한 영상을 균일하게 만들어 줌.

영상의 밝기 분포를 재분배하여 명암 대비를 최대화

 

 

<히스토그램 평활화>

        //히스토그램 평활화
        function histoSmoothing() {

            clickEventDown();
            //1단계
            smoothingArr = new Array(256);

            for (var i = 0; i < outHeight; i++)
                for (var k = 0; k < outWidth; k++) {
                    smoothingArr[i] = 0;
                }

            for (var i = 0; i < outHeight; i++)
                for (var k = 0; k < outWidth; k++) {
                    pixel = outImageArray[i][k].charCodeAt(0);
                    smoothingArr[pixel]++;
                }

            //2단계 누적 히스토그램 생성
            var allSumHisto = new Array(256);

            for (var i = 0; i < 256; i++)
                allSumHisto[i] = 0;

            sumValue = 0;

            for (var i = 0; i < 256; i++) {
                sumValue += smoothingArr[i];
                allSumHisto[i] = sumValue;
            }

            //3단계 정규화된 누적 히스토그램
            normalHisto = new Array(256);
            for (var i = 0; i < 256; i++)
                normalHisto[i] = 0;

            for (var i = 0; i < 256; i++)
                normalHisto[i] = allSumHisto[i] * (1 / (outWidth * outHeight)) * 255;

            for (var i = 0; i < outHeight; i++)
                for (var k = 0; k < outWidth; k++) {
                    valueOfInImage = outImageArray[i][k].charCodeAt(0);
                    formula = normalHisto[valueOfInImage];

                    if (formula > 255)
                        formula = 255;
                    else if (formula < 0)
                        formula = 0;
                    else
                        formula = parseInt(formula);

                    outImageArray[i][k] = String.fromCharCode(formula);
                }

            displayImage();
            clickEvent();
        }

1. 256크기의 배열을 하나 생성 후 배열의 요소를 모두 0으로 초기화

2. 명도의 빈도 수 smoothingArr에 저장 (1단계)

 ex) 24, 5, 10 --> smoothingArr[24] = 1, smoothing[5] = 1, smoothing[10] = 1

3. 빈도 수를 누적합을 구해서 저장 (2단계)

 ex) smoothingArr[0] = 1 , smoothingArr[1] = 2, smoothingArr[2] = 5

smoothingArr[0] =1, smoothinArr[1] = 3, smoothingArr[2] = 8 --> 누적합

4. 히스토그램 스트레칭 기법을 쓰는데 누적합을 사용해서 적용

5. 값이 0부터 255인지 확인

6. 출력하는 메소드 호출

 

 

 

 

--> 히스토그램 평활화 결과화면

728x90