제 9 장 영상압축
학습목표 영상 압축의 필요성 및 유형을 이해한다 런길이 부호화의 개념을 이해한다 허프만 코딩 알고리즘을 이해한다 JEPG 압축 및 복원 방법을 이해한다 2018-11-24 영상처리
영상 압축의 필요성 압축되지 않은 비디오 자료의 저장공간 640 x 480 x 3 바이트/프레임 x 30 프레임/초 = 26.4 MB / 초 한 시간의 동영상저장 26.4 MB / 초 X 3600 초 = 95 GB 2018-11-24 영상처리
영상압축의 두 가지 유형 무손실 압축 손실 압축 부호화된 자료가 완벽하게 복원됨 처리상에서 자료의 손실이 없으므로 영상의 질이 저하되지 않음 손실 압축 중복되고 중요도가 떨어지는 정보가 손실되는 것을 허용 압축률은 좋지만 질적 저하를 가져옴 2018-11-24 영상처리
런 길이 부호화(Run length Encoding) 자료의 반복성을 이용하는 가장 간단한 압축 기법 만화와 같은 단순 그림에 적합 (예) AAAABBBBBCCCCCCCCDEEEE 4A5B8C1D4E 압축률 = 22 바이트/ 10 바이트 = 2.2 2018-11-24 영상처리
런 길이 부호화의 단점 반복된 자료에 적용하지 않으면 비효율적임 (예) MyDogHasFleas 1M1y1D1o1g1H1a1s1F1l1e1a1a 압축률 = 13 바이트 / 26 바이트 = 0.5 2018-11-24 영상처리
런 길이 부호화의 보완 보완방법 런 길이를 나타내기 위해 앞에다 특수문자 삽입 (예) 반복되지 않는 데이터는 그대로 표현 런 길이 부호화는 단지 반복된 자료에 적용 런 길이를 나타내기 위해 앞에다 특수문자 삽입 (예) ABCDDDDDDDDEEEEEEEEE ABC*8D*9E 압축률 = 19bytes/9bytes = 2.11 2018-11-24 영상처리
런길이 부호화 형식 예 런길이 부호화를 사용한 정지영상 형식 PCX 형식 PCX, RLE, GEM 등 런 길이를 나타내는 특수 기호를 런 길이와 같은 바이트에 저장 2018-11-24 영상처리
PCX 형식 PCX를 사용한 부호화 예 FF F5 C1 C5 01 05 1A 1C 3F (a) (b) (c) 2018-11-24 영상처리
허프만 코딩 데이터의 발생 빈도수에 따라 다른 길이의 코드 사용 (예) T O U P E E 111 0100 10111 10110 100 100 2018-11-24 영상처리
허프만 코딩 알고리즘 처음에는 모든 빈도수들을 독립된 자유 노드들로 간주 가장 낮은 빈도수를 가진 두 개의 자유 노드들을 자식노드로 하는 하나의 부모 노드를 생성 부모 노드는 자식 노드들의 합과 동일한 가중치를 가짐 가중치가 높은 노드가 왼쪽 자식으로 채택됨 연결된 두개의 자식 노드들을 자유 노드 리스트에서 제거하고 부모 노드를 리스트에 추가함 2, 3단계를 하나의 자유 노드만 남을 때까지 반복 코드 할당 : 왼쪽 자식 = 0 오른쪽 자식 = 1 2018-11-24 영상처리
허프만 코딩 알고리즘 픽셀 값의 빈도수 입력 영상 픽셀값 빈도수 2018-11-24 영상처리 18 100 12 60 11 70 30 60 70 80 100 120 픽셀값 빈도수 18 100 12 60 11 70 8 30 6 80 5 20 3 120 1 픽셀 값의 빈도수 입력 영상 2018-11-24 영상처리
허프만 코딩 알고리즘 이진 트리 생성 과정 2018-11-24 영상처리
허프만 코딩 알고리즘 2018-11-24 영상처리
허프만 코딩 알고리즘 2018-11-24 영상처리
허프만 코딩 알고리즘 허프만 코드 할당 1 1 1 1 1 1 1 허프만 코드 픽셀값 코드 2018-11-24 영상처리 01 01 100 11 60 000 70 30 101 80 0010 20 00110 120 00111 1 1 1 1 1 1 1 허프만 코드 2018-11-24 영상처리
허프만 코딩의 단점 부호화시 두 단계를 필요로 함 첫 번째 과정을 제거하는 한 방법으로 고정된 표를 사용 1. 문자의 빈도수를 측정 2. 압축 수행 첫 번째 과정을 제거하는 한 방법으로 고정된 표를 사용 압축되어질 모든 자료군을 최적화하지는 못함 수정된 허프만 코딩 기법에서 고정된 표를 사용 2018-11-24 영상처리
JPEG Joint Photographic Experts Group에 의해서 표준화된 압축기법 인간의 시각 시스템의 한계 활용 사람의 시각은 세밀한 부분까지 인지하지 않음 밝기와 컬러 밝기 변화에 민감 컬러 색상의 변화에 민감하지 못함 컬러 정보를 더 많이 제거 2018-11-24 영상처리
JPEG 흑백 또는 컬러 사진의 압축에 적합 여러 가지 압축 모드 제공 만화 같은 단순 영상의 압축에는 부적합 이러한 영상에는 GIF가 적합 여러 가지 압축 모드 제공 순차적 인코딩 점진적 인코딩 무손실 인코딩 계층적 인코딩 결과 영상의 화질에 대한 수준(Q 인자)을 지정하여 압축 좋은 화질을 원할 수록 파일 크기는 커짐 2018-11-24 영상처리
JPEG 압축 단계 영상의 컬러 모델을 RGB에서 YCbCr(Y=휘도/CbCr=색도)로 변환 색도 성분 다운샘플링(선택 사항) 영상을 8x8 화소의 블록들로 분할 각 블록에서 DCT(Discrete Cosine Transform) 실행 DCT 계수를 양자화 양자화된 DCT 계수를 허프만 코딩 방법을 사용하여 암호화 2018-11-24 영상처리
JPEG 압축 단계 컬러 모델 변환 색도 성분 다운샘플링 휘도 구성요소보다 색도 구성요소에서 보다 많은 정보 제거 휘도 구성요소 : 원래 해상도 유지 색도 구성요소 수평과 수직 방향으로 부표본화(subsampling) 2018-11-24 영상처리
JPEG 압축 단계 영상을 8x8 화소의 블럭들로 분할하고 각 블록에서 DCT수행 저주파 7 7 고주파 주파수 영역으로 변환 7 (0,0) 원소를 DC 값으로 표시 나머지 원소는 ACyx로 표시 7 고주파 2018-11-24 영상처리
JPEG 압축 단계 입력 영상 DCT 계수 2018-11-24 영상처리 139 144 149 153 155 151 156 159 150 160 163 158 161 162 157 235.6 -1.0 -12.1 -5.2 2.1 -1.7 -2.7 1.3 -22.6 -17.5 -6.2 -3.2 -2.9 -0.1 0.4 -1.2 -10.9 -9.3 -1.6 1.5 0.2 -0.9 -0.6 -7.1 -1.9 0.9 0.0 0.3 -0.8 1.6 -0.7 0.6 1.8 -0.2 -0.3 1.0 -1.3 -0.4 -1.5 -0.5 1.7 1.1 -2.6 -3.8 -1.8 1.9 1.2 입력 영상 DCT 계수 2018-11-24 영상처리
JPEG 압축 단계 DCT 계수를 양자화 DCT 계수를 양자화 계수로 나눈 다음 반올림 Q 값에 따라 양자화 계수가 달라짐 Q 값이 낮을 수록 많은 수의 DCT 계수가 0의 값으로 양자화 되도록 계수 설정 양자화 계수의 예 : 표 9.4, 표 9.5 양자화의 기능 고주파 정보를 제거 2018-11-24 영상처리
JPEG 압축 단계 양자화 결과 표 9.4 : 밝기 성분에 대한 양자화 계수 15 -1 -2 16 11 10 24 40 51 61 12 14 19 26 58 60 55 13 57 69 56 17 22 29 87 80 62 18 37 68 109 103 77 35 64 81 104 113 92 49 78 121 120 101 72 95 98 112 100 99 15 -1 -2 표 9.4 : 밝기 성분에 대한 양자화 계수 양자화 결과 2018-11-24 영상처리
JPEG 압축 단계 색도 성분에 대한 양자화 계수 값 17 18 24 47 99 21 26 66 56 2018-11-24 영상처리
JPEG 압축 단계 양자화된 DCT 계수의 부호화 지그재그 순서로 부호화 허프만 코딩 방법으로 부호화 15 -1 -2 양자화 계수 값의 부호화 순서 부호화할 계수 : 15, 0, -2, -1, -1, -1, 0,0,-1, …, 0 2018-11-24 영상처리
JPEG 압축 단계 연속된 0과 그 다음의 0이 아닌 DCT 계수의 집합이 심볼-1 + 심볼-2 로 인코딩됨 심볼-1 : (RUNLENGTH, SIZE) RUNLENGTH 0 의 길이 SIZE 0 이 아닌 DCT 계수(심볼-2)에 대한 코드 길이 심볼-2 0이 아닌 DCT 계수의 코드값 블록의 끝(EOB) 1010 : RUNLENGTH = 0, SIZE = 0 2018-11-24 영상처리
JPEG 압축 단계 DC 값의 인코딩 이전 블록의 DC값과의 차이를 인코딩 심볼-1 심볼-2 0의 런 길이는 고려 안 함 DC 값을 인코딩 하는데 필요한 비트 수에 대한 코드 값 심볼-2 코드화된 DC 값 예) 부호화할 계수 : 15, 0, -2, -1, -1, -1, 0,0,-1, …, 0 DC = 15임, 이전 블록의 DC = 18일 때 DC값 차이 = -3 -3을 인코딩하기 위해서 2비트 사용(표 9.6 참조) 숫자 2에 대한 코드 값 = 011 (표 9.7 참조) 심볼-1 = 011 -3의 코드값 = 00 (표 9.10 참조) 심볼-2 = 00 결과 코드값 = 01100 2018-11-24 영상처리
표 9.6 계수 값과 SIZE의 관계 SIZE AMPLITUDE 1 2 3 4 5 6 7 8 9 10 -1, 1 -3,-2,2,3 -7,-6,-5,-4,4,5,6,7 -15..-8, 8..15 -31..-16,16..31 -63..-32,32..63 -127..-64,64..127 -255,-128,128..255 -511..-256,256..511 -1023..-512,512..1023 2018-11-24 영상처리
표 9.7 심볼-1에 대한 코드(DC 성분) 밝기 성분에 대한 코드 심볼 1 코드 1 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 6 7 8 9 10 11 00 010 011 100 101 110 1110 11110 111110 1111110 11111110 111111110 2018-11-24 영상처리
표 9.10 심볼-2에 대한 코드 예 심볼-2 코드 -1 1 -3 00 -2 01 2 10 3 11 -7 000 -6 001 1 -3 00 -2 01 2 10 3 11 -7 000 -6 001 -5 010 -4 011 4 100 5 101 6 110 7 111 -15 0000 -14 0001 -13 0010 -12 0011 -11 0100 -10 0101 -9 0110 -8 0111 8 1000 9 1001 10 1010 11 1011 12 1100 13 1101 14 1110 15 1111 -31 00000 -30 00001 -29 00010 -28 00011 -27 00100 -26 00101 -25 00110 -24 00111 -23 01000 -22 01001 -21 01010 -20 01011 -19 01100 -18 01101 -17 01110 -16 01111 16 10000 17 10001 18 10010 19 10011 20 10100 21 10101 22 10110 23 10111 24 11000 25 11001 26 11010 27 11011 28 11100 29 11101 30 11110 31 11111 2018-11-24 영상처리
JPEG 압축 단계 AC 값의 인코딩 심볼-1 심볼-2 (RUNLENGTH, SIZE)에 따른 코드 (표 9.8) 0이 아닌 수의 코드 값 (표 9.10) 2018-11-24 영상처리
JPEG 압축 단계 부호화할 계수 : 15, 0, -2, -1, -1, -1, 0,0,-1, …, 0 부호화할 계수 : 15, 0, -2, -1, -1, -1, 0,0,-1, …, 0 심볼 : (2) (-3), (1,2) (-2), (0,1)(-1), (0,1)(-1), (0,1)(-1), (2,1) (-1), (0,0) 코드 : 011 00 11011 01 00 0 00 0 00 0 11100 0 1010 (1,2)(-2) RUNLENGTH = 1, SIZE = 2 심볼-1 = 11011 (표 9.8) -2 심볼-2 = 01 (표 9.10) (0,1)(-1) RUNLENGTH = 0, SIZE = 1 심볼-1 = 00 (표 9.8) -1 심볼-2 = 0 (표 9.10) (2,1)(-1) RUNLENGTH = 2, SIZE = 1 심볼-1 = 11100 (표 9.8) 2018-11-24 영상처리
표 9.8 밝기(Y) 성분 심볼-1 코드 예 심볼-1 코드 (0,1) 00 (1,1) 1100 (2,1) 11100 (0,2) 01 (1,2) 11011 (2,2) 11111001 (0,3) 100 (1,3) 1111001 (2,3) 1111110111 (0,4) 1011 (1,4) 111110110 (2,4) 111111110110 (0,5) 11010 (1,5) 1111110110 (2,5) 1111111110001001 (0,6) 1111000 (1,6) 1111111110000100 (2,6) 1111111110001010 (0,7) 11111000 (1,7) 1111111110000101 (2,7) 1111111110001011 (0,8) (1,8) 1111111110000110 (2,8) 1111111110001100 (0,9) 1111111110000010 (1,9) 1111111110000111 (2,9) 1111111110001101 (0,10) 1111111110000011 (1,10) 1111111110001000 (2,10) 1111111110001110 2018-11-24 영상처리
부호화 결과 139 144 149 153 155 151 156 159 150 160 163 158 161 162 157 0110011011010000000001110001010 31비트 64 x 8 = 512비트 2018-11-24 영상처리
영상 복원 압축 과정의 역순 코드값 심볼 심볼 양자화 계수값 역 양자화 역방향 DCT 컬러모델 변환 2018-11-24 영상처리
영상 복원 0110011011010000000001110001010 코드값 심볼 (2) (-3), (1,2) (-2), (0,1)(-1), (0,1)(-1), (0,1)(-1), (2,1) (-1), (0,0) 심볼 양자화 계수값 15 -1 -2 역 양자화 2018-11-24 영상처리
영상 복원 240 -10 -24 -12 -14 -13 역 양자화 역방향 DCT 2018-11-24 영상처리
영상 복원 144 146 149 152 154 156 155 157 158 160 161 162 159 163 164 역방향 DCT 2018-11-24 영상처리
영상 복원 원영상과의 비교 복원된 영상 원 영상 2018-11-24 영상처리 144 146 149 152 154 156 155 157 158 160 161 162 159 163 164 139 144 149 153 155 151 156 159 150 160 163 158 161 162 157 복원된 영상 원 영상 2018-11-24 영상처리
JPEG 압축 예 6K바이트 88K바이트 15K바이트 원영상 2018-11-24 영상처리
기본적인 JPEG 파일 형식 기본적인 JPEG 파일의 구조 SOI 표시자로 시작 EOI 표시자로 종료 프레임과 스캔 2바이트 값 : FFD8 EOI 표시자로 종료 2바이트 값 : FFD9 프레임과 스캔 이미지 정보 저장 점진적 JPEG등에서는 하나의 영상(프레임)에 여러가지 모습(스캔) 저장 가능 기본적인 JPEG에서는 하나의 프레임에 하나의 스캔만 저장 코드 세그먼트 부호화된 실제 코드 값 저장 테이블 양자화 테이블, 허프만 테이블 등 SOI 표시자 프레임 EOI 헤더 스캔 테이블 및 기타 표시자 코드 세그먼트 블럭 … 기본적인 JPEG 파일의 구조 2018-11-24 영상처리
기본적인 JPEG 파일 형식 JPEG 표시자 예 표시자 값 표시자 코드 내용 FFD8 SOI(Start Of Image) 이미지 시작 FFD9 EOI(End Of Image) 이미지 끝 FFDA SOS(Start Of Scan) 스캔 헤더 시작 FFDB DQT(Define Quantization Table) 양자화 테이블 정의 FFC4 DHT(Define Huffman Table) 허프만 테이블 정의 FFC0 SOF0(Start Of Frame 0) 기본적인 JPEG 프레임 시작 FFC1 SOF1(Start Of Frame 1) 계층적 JPEG 프레임 시작 FFC2 SOF2(Start Of Frame 2) 점진적 JPEG 프레임 시작 FFC3 SOF3(Start Of Frame 3) 무손실 JPEG 프레임 시작 FFFE COM(comment) 설명문 FFF0 - FFFD JPG JPEG 확장을 위해 예약된 영역 2018-11-24 영상처리
기본적인 JPEG 파일 형식 양자화 테이블 부호화에 사용된 양자화 테이블 저장 구성 요소 기본적인 JPEG DQT 표시자(2바이트) : FFDB 테이블의 크기(2바이트) 정밀도(4비트) : 테이블 값이 몇 비트인지 지정 정밀도 = 0 8 비트, 정밀도 = 1 16비트 테이블번호(4비트) : 0번과 1번 사용 양자화 테이블 값(64바이트) : 양자화 값이 지그재그 형태로 저장 기본적인 JPEG 흑백 영상은 밝기 성분에 대한 양자화 테이블(표 9.4) 저장 컬러 영상은 밝기 성분에 대한 양자화 테이블 (표 9.4)과 색도 성분에 대한 양자화 테이블(표 9.5)을 저장 DQT 표시자 테이블 크기 정밀도 번호 양자화 2018-11-24 영상처리
기본적인 JPEG 파일 형식 허프만 테이블 기본적인 JPEG 파일에는 4가지의 테이블을 저장 밝기 성분에 대한 DC 값의 심볼-1에 대한 코드(표 9-7(a)) 색도 성분에 대한 DC 값의 심볼-1에 대한 코드(표 9-7(b)) 밝기 성분에 대한 AC 값의 심볼-1에 대한 코드(표 9-8) 색도 성분에 대한 AC 값의 심볼-1에 대한 코드(표 9-9) 2018-11-24 영상처리
기본적인 JPEG 파일 형식 허프만 테이블 구성 요소 DHT 표시자(2바이트) : FFC4 테이블의 크기(2바이트) 테이블번호(1바이트) : DC 테이블은 0~15, AC 테이블 16이상의 번호사용 허프만 코드 길이별 빈도수 JPEG에서 허프만 코드 길이 : 1부터 16까지 사용 16가지 길이별 코드 빈도수가 16바이트에 걸쳐서 저장 코드 길이별 빈도수가 주어지면 허프만 코드를 생성할 수 있음 심볼 각 허프만 코드별로 한바이트씩 심볼을 저장 DC 성분 : 한 값으로 구성(코드의 비트수) AC 성분 : 두 값의 쌍으로 구성(상위 4비트: 0의 반복수, 하위 4비트 : 코드의 비트 수) DHT 표시자 테이블 크기 번호 허프만 코드 길이별 빈도수 심볼 … 2018-11-24 영상처리
기본적인 JPEG 파일 형식 허프만 코드 길이별 빈도수 예 심볼 1 코드 1 2 3 4 5 6 7 8 9 10 11 00 2 3 5 4 6 7 8 9 10 11 12 13 14 15 16 심볼 1 코드 1 2 3 4 5 6 7 8 9 10 11 00 010 011 100 101 110 1110 11110 111110 1111110 11111110 111111110 밝기 성분에 대한 심볼-1의 허프만 테이블 (표 9-7(a)) 허프만 코드 길이별 빈도수 2018-11-24 영상처리
기본적인 JPEG 파일 형식 허프만 코드 길이별 빈도수로부터 허프만 코드 생성 허프만 코드는 0으로 시작 다음 코드가 이전코드와 길이가 같으면 다음 코드 값은 이전 코드에 1을 더한 값을 갖는다 코드 길이가 다르게 되면 다음 코드는 이전 코드에 1을 더한 다음에 두 코드 길이 차이만큼 2를 곱한 값을 갖는다 표 9-7(a) 에서 1 번째 코드는 길이가 2이고 한 개 코드값 = 00 2 번째 코드는 길이가 3 코드값 = 010 (이전 코드 00 에 1을 더한 다음에 2를 곱하면 010) 3, 4, 5, 6번째 코드는 코드 길이가 같으므로 코드는 연속해서 증가 코드값 = 011, 100, 101, 110 7 번째 코드는 길이가 4 코드값 = 코드 길이가 달라지므로 110에 1을 더한 다음에 2를 곱하면 1110 이렇게 구한 코드 값은 표 9-7(a)의 허프만 코드와 일치한다. 코드 길이 빈도수 코드 (이진수) 1 2 00 3 5 010 011 100 101 110 4 1110 11110 6 111110 7 1111110 8 11111110 9 111111110 10 ~16 2018-11-24 영상처리
기본적인 JPEG 파일 형식 DC 성분에 대한 심볼 저장 예 저장되는 심볼 값 1 2 3 4 5 6 7 8 9 10 11 심볼 1 코드 1 2 3 4 5 6 7 8 9 10 11 00 010 011 100 101 110 1110 11110 111110 1111110 11111110 111111110 한 바이트 저장되는 심볼 값 1 2 3 4 5 6 7 8 9 10 11 2018-11-24 영상처리
기본적인 JPEG 파일 형식 AC 성분에 대한 심볼 저장 예 심볼-1 코드 (0,1) 00 (0,2) 01 (0,3) 100 (0,0) 1010 (0,4) 1011 (1,1) 1100 (0,5) 11010 (1,2) 11011 … AC 성분에 대한 심볼 저장 예 표 9-8의 밝기 성분 AC 값의 심볼-1에 대한 테이블은 심볼 순으로 정렬되어 있음 JPEG 파일에 저장하기 위해서 표 9-8을 코드 순서로 재배열해야 함 저장 심볼 값은 코드 순서에 따라 우측그림과 같이됨 심볼이 (1, 1)인 경우 상위 4비트의 값이 1이고 하위 4비트의 값이 1이므로 이진수로 “00010001”이되고 이것은 10진수로 17이된다 한 바이트 1 2 3 4 17 5 18 … 저장되는 심볼 값 2018-11-24 영상처리
기본적인 JPEG 파일 형식 프레임 헤더 구성 요소 SOF 표시자(2바이트) : FFC0 (기본적인 JPEG) 헤더 길이(2바이트) 샘플링 정밀도(1바이트) : 기본적인 JPEG에서는 보통 8의 값을 가짐 영상 높이(2바이트) 영상 넓이(2바이트) 컴포넌트 수만큼 반복 SOF 표시자 헤더 길이 샘플링 정밀도 영상 높이 넓이 컴포넌트 수 번호 수평 비율 수직 양자화 테이블 … 2018-11-24 영상처리
기본적인 JPEG 파일 형식 구성 요소 (계속) 수평/수직 샘플링비율은 컴포넌트 사이의 상대적 비율임 컴포넌트 수(1바이트) : 흑백 영상 = 1, 컬러 영상 = 3 컴포넌트번호(1바이트) 수평샘플링비율(4비트) 수직샘플링비율(4비트) 양자화테이블번호(1바이트) 수평/수직 샘플링비율은 컴포넌트 사이의 상대적 비율임 A 컴포넌트의 값이 2이고 B 컴포넌트 값이 1인 경우 B 컴포넌트에 비해 A 컴포넌트를 2배 더 샘플링하여 2배의 정보를 저장 2018-11-24 영상처리
기본적인 JPEG 파일 형식 스캔 헤더 SOS 표시자(2바이트) : FFDA 헤더길이(2바이트) 컴포넌트수(1바이트) 컴포넌트번호(1바이트) 허프만 테이블번호(1바이트) 상위 4비트 : DC 값에 대한 테이블번호 하위 4비트 : AC 값에 대한 테이블번호 바이트 1, 2, 3 : 기본적인 JPEG에서는 사용안됨 SOS 표시자 헤더 길이 컴포넌트 수 번호 허프만 테이블 바이트 1 2 3 … 2018-11-24 영상처리
기본적인 JPEG 파일 형식 코드 세그먼트 코드 블록들의 집합 코드 블록 8 x 8 크기로 분할된 영역에 대한 부호화된 코드 저장 2018-11-24 영상처리
실습
PCX 파일 복원 메뉴막대에 [영상 압축 및 복원] 메뉴 추가 [영상 압축 및 복원]메뉴에 부메뉴 추가 이름 : 영상 압축 및 복원 [영상 압축 및 복원]메뉴에 부메뉴 추가 이름 : PCX 복원 ID : ID_LOAD_PCX 2018-11-24
PCX 파일 복원 CImageProView 클래스에 OnLoadPCX() 함수를 추가하고 다음과 같이 편집 void CImageProView::OnLoadPCX() { CImageProDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); pDoc->LoadPCX(); viewMode = TWO_IMAGES; Invalidate(FALSE); } 2018-11-24
PCX 파일 복원 CImageProDoc 클래스에 LoadPCX() 함수 추가 반환 형식: void 함수 이름: LoadPCX 2018-11-24 영상처리
PCX 파일 복원 LoadPCX() 함수를 다음과 같이 편집 typedef struct PCX_HEADER { char manufacturer; char version; char encoding; char bits_per_pixel; short int xmin,ymin; short int xmax,ymax; short int hres; short int vres; char palette16[48]; char reserved; char color_planes; short int bytes_per_line; short int palette_type; char filler[58]; } pcx_header; 2018-11-24 영상처리
PCX 파일 복원 void CImageProDoc::LoadPCX() { int i, x, y; int run_length; unsigned char c; pcx_header pcxhead; CString fname; CFile file; CFileDialog dlg(TRUE); if(dlg.DoModal()==IDOK) { fname = dlg.GetPathName(); // 파일 이름 받아오기 file.Open(fname, CFile::modeRead); // 파일 열기 2018-11-24 영상처리
PCX 파일 복원 if (strcmp(strrchr(fname, '.'), ".PCX") == 0 || // 파일 확장자 확인 { file.Read(&pcxhead, sizeof(pcx_header)); // 헤더를 읽어 들임 imageWidth = (pcxhead.xmax-pcxhead.xmin) + 1; // 영상의 넓이 계산 imageHeight = (pcxhead.ymax-pcxhead.ymin) + 1; // 영상의 높이 계산 depth = pcxhead.color_planes; if (depth != 1) return; // 기억장소 할당 inputImg=(unsigned char **) malloc(imageHeight*sizeof(unsigned char *)); resultImg=(unsigned char **) malloc(imageHeight*sizeof(unsigned char *)); for (i = 0; i < imageHeight; i++) { inputImg[i] = (unsigned char *) malloc(imageWidth * depth); resultImg[i] = (unsigned char *) malloc(imageWidth * depth); } 2018-11-24 영상처리
PCX 파일 복원 for (y = 0; y < imageHeight; y++) for (x = 0; x < imageWidth; ) { file.Read(&c, 1); // 한 바이트를 읽어 들임 if((c & 0xc0) == 0xc0) // 런 길이를 포함하는 바이트이면 run_length = c & 0x3f; // 런 길이 계산 file.Read(&c, 1); // 데이터를 읽어들임 while(run_length--) // 런 길이만큼 저장 inputImg[y][x++] = c; } else // 런 길이를 포함하는 바이트가 아니면 2018-11-24 영상처리
PCX 파일 복원 [영상 압축 및 복원] 메뉴에서 [PCX 복원] 항목을 선택한 다음에 “twopills.pcx" 파일 선택 2018-11-24 영상처리
PCX 파일 압축 [영상 입축 및 복원] 메뉴 아래에 PCX 형식 부호화를 위한 부메뉴를 추가 이름 : PCX 압축 ID : ID_SAVE_PCX 2018-11-24 영상처리
PCX 파일 압축 CImageProView 클래스에 OnSavePCX() 함수를 추가하고 다음과 같이 편집 void CImageProView::OnSavePCX() { CImageProDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (pDoc->inputImg == NULL) return; pDoc->SavePCX(); viewMode = TWO_IMAGES; Invalidate(FALSE); } 2018-11-24 영상처리
PCX 파일 압축 CImageProDoc 클래스에 SavePCX() 함수 추가 반환 형식: void 함수 이름: SavePCX 2018-11-24 영상처리
PCX 파일 압축 SavePCX() 함수를 다음과 같이 편집 void CImageProDoc::SavePCX() { int i, x, y; int run_length; unsigned char c; unsigned char cur; unsigned char prev; pcx_header pcxhead; CString fname; CFile file; CFileDialog dlg(TRUE); if(dlg.DoModal()==IDOK) { fname = dlg.GetPathName(); // 파일 이름 받아오기 file.Open(fname, CFile::modeCreate | CFile::modeWrite); // 파일 열기 2018-11-24 영상처리
PCX 파일 압축 if (strcmp(strrchr(fname, '.'), ".PCX") == 0 || // 파일 확장자 확인 { memset(&pcxhead, 0, 128); // 헤더 내용을 0으로 초기화 pcxhead.manufacturer = 10; // 기본 값 pcxhead.version = 5; // 기본 값 pcxhead.encoding = 1; // 런 길이 부호화 사용 pcxhead.bits_per_pixel = 8; // 픽셀 당 8 비트 pcxhead.xmin = 0; pcxhead.ymin = 0; pcxhead.xmax = imageWidth - 1; pcxhead.ymax = imageHeight - 1; pcxhead.hres = 150; // 150 DPI pcxhead.vres = 150; // 150 DPI pcxhead.color_planes = 1; pcxhead.bytes_per_line = imageWidth; pcxhead.palette_type = 1; file.Write(&pcxhead, 128); // 헤더 출력 2018-11-24 영상처리
PCX 파일 압축 for (y = 0; y < imageHeight; y++) { // 각 라인에 대하여 run_length = 0; for (x = 0; x < imageWidth; x++) { // 각 픽셀에 대하여 cur = inputImg[y][x]; run_length++; if (x < imageWidth - 1 && cur == inputImg[y][x+1] && run_length < 63) { // 라인의 끝이 아니고 다음에 같은 픽셀이 반복되고 // 런길이가 63보다 작으면 // ==> 다음 픽셀로 이동 } 2018-11-24 영상처리
PCX 파일 압축 else if (run_length > 1 || (0xC0 & cur) == 0xC0) { // 런 길이가 1보다 크거나 런 길이가 1이지만 상위 두 비트 값이 1인 경우 // ==> 런 길이 바이트와 데이터 바이트 저장 c = 0xC0 | (unsigned char) run_length; file.Write(&c, 1); file.Write(&cur, 1); run_length = 0; } else { // 런 길이가 1이고 상위 두 비트 값이 1이 아닌 경우 // ==> 데이터 바이트만 저장 file.Close(); 2018-11-24 영상처리
PCX 파일 압축 프로그램을 컴파일하고 실행 Lenna.raw 영상을 열은 다음 [영상 압축 및 복원] 메뉴에서 [PCX 압축] 항목을 선택 파일 선택 대화 상자가 나타나면 “Lenna.pcx" 이름을 지정 2018-11-24 영상처리
PCX 파일 압축 생성된 “Lenna.pcx“ 파일 불러들여서 확인 Lenna 영상이 출력된 윈도우를 닫고, [PCX 복원] 항목을 선택한 다음 “Lenna.pcx" 파일 선택 2018-11-24 영상처리