전시작품으로 입선했지만 상위권에 들지는 못했습니다.

내년에 다른 주제로 공모전을 할때는 구체적인 계획과 많은 시간을 투자하여 좋은 결과를 얻을 수 있도록 하겠습니다.

이렇게 좋은 경험을 할 수 있도록 서포트해주신 멘토님께 정말 감사드립니다.

또 저와 함께 일년동안 공모전을 준비한 팀원들에게도 감사합니다.

좋은 경험이 되었던 것 같습니다.

  • 작품 소개

    • 학습시킨 모델을 가진 디바이스가 행인들의 안면을 인식, 성별 및 나이를 판단하여 그에 맞는 광고를 보여 주려고 합니다. 수많은 사람들의 얼굴 데이터를 모아서 딥러닝을 통하여 연령과 성별을 분류해주는 모델을 만듭니다. 만들어진 모델을 라즈베리파이에 넣고 캠을 통한 행인들의 캡처이미지를 입력하여 줍니다. 작동 후 나오게 된 결과 데이터를 통해 분류된 클래스에 따른 광고를 띄워주는 것이 목표입니다.

  • 시스템 구성도

 

  • 시스템 흐름도

  • 프로그램(기능) 목록

  • 기능 흐름도

  • 프로젝트 수행일정

프로젝트 기간 (한이음 사이트 기준)

2018 . 4 . 24 ~ 2018 . 11 . 30

 

구분

추진내용

프로젝트 기간

1

2

3

4

5

6

7

8

9

10

11

12

계획

시나리오 계획, 계획서 작성

 

 

 

 

 

 

 

 

 

 

 

 

분석

OpenCV + 얼굴인식

, 나이 분석(소스,논문)

CNN(input,output)

 

 

 

 

 

 

 

 

 

 

 

 

설계

HW 부품 구입 및 설계

 

 

 

 

 

 

 

 

 

 

 

 

Software 알고리즘 설계

 

 

 

 

 

 

 

 

 

 

 

 

개발

HW 설치 및 동작 확인

 

 

 

 

 

 

 

 

 

 

 

 

OpenCV를 이용하여 얼굴영역 추출

-> 딥러닝을 통한 성별과 나이분석

 

 

 

 

 

 

 

 

 

 

 

 

응급상황 출력 알고리즘 개발

 

 

 

 

 

 

 

 

 

 

 

 

테스트

위 개발 내용을 종합한 프로토타입 테스트 및 보완

 

 

 

 

 

 

 

 

 

 

 

 

종료

프로젝트 종료

 

 

 

 

 

 

 

 

 

 

 

 

  • 작품의 개발배경 및 필요성 
    • 최근 딥러닝을 이용한 ICT디바이스 기술이 발전하면서 없어서는 안 될 기술이 되었습니다. 이러한 트렌드를 맞추고 수많은 정보로 가득 찬 세상에서 수동적인 광고 시스템이 아닌 고객의 니즈를 파악해 능동적으로 적합한 광고 시스템이 필요하다 느꼈습니다

 

  • 작품의 특장점
    • 특징 : 사람의 얼굴을 인식해 나이와 성별을 파악 후 연령대/성별 맞춤광고를 제공합니다.

    • 장점 : 계속 반복되는 광고를 보여주는 것 보다 타겟으로 삼는 사람들에게 맞춰진 광고를 보여줄 수 있으므로 훨씬 더 효율적입니다.

  • 작품의 기대효과 및 활용분야

  •       광고 효율 증가 맞춤형 광고를 통해 단순하게 반복되는 광고보다 효율이 높습니다.

  •        응급처치 시스템 주변에 응급상황 발생 시 응급처치 방법을 제공해 인명을 구조 할 수 있습니다.

  •        전력 절약 고객이 없을 때 모니터 off로 불필요한 전력 소비를 막을 수 있습니다.


지금까지 배운 내용을 토대로 10가지 정도의 이미지 프로세싱 알고리즘을 opencv로 구현하여 매트랩에서 제공하는 함수와의 차이를 확인해보자

 

  • Quantization

  • 매트랩 코드
1
2
3
4
5
6
7
8
clear; clc;
x=imread('boat.png');
f=floor(double(x)/32);
q1=uint8(f*32);
subplot(1,2,1), imshow(x), subplot(1,2,2), imshow(q1);
 
[psnr, snr] = psnr(x,q1);
psnr 
cs

 

  • opencv 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <stdio.h>
#include <Windows.h>
#include "opencv2/opencv.hpp"
#include <cmath>
 
using namespace cv;
 
void ft_color_depth_reduction(Mat &image, int labels){
 
    int h = image.rows; // height (영상의 높이)
    int w = image.cols; // width (영상의 너비)
 
    for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
            // 0-255 level (gray image) 인 경우 :
            if (image.channels() == 1)
            {
                uchar data = image.at<uchar>(y, x);
                data = data / labels * labels + labels / 2;
                image.at<uchar>(y, x) = data;
            }
            // RGB level (color image) 인 경우 :
            else if (image.channels() == 3)
            {
                Vec3b colVal = image.at<Vec3b>(y, x);
                colVal[2= colVal[2/ labels * labels + labels / 2;
                colVal[1= colVal[1/ labels * labels + labels / 2;
                colVal[0= colVal[0/ labels * labels + labels / 2;
                image.at<Vec3b>(y, x) = colVal;
            }
        }
    }
}
void main()
{
    Mat srcimage = imread("boat.png"-1); // 변환할 영상
 
    if (!srcimage.data)
    {
        printf("No Image Found\n");
        return;
    }
    namedWindow("Original Image", WINDOW_AUTOSIZE);
    imshow("Original Image", srcimage);
    Mat outimage = srcimage.clone();
    int num = 32;
    ft_color_depth_reduction(outimage, num);
    imshow("Output Image", outimage);
    waitKey(0);
    destroyAllWindows();
}
cs
  •  결과 사진 비교

    1. 매트랩

   

2.   opencv

  • 이미지 회전

  • 매트랩 코드

  • opencv 코드

  • 결과비교

    1. 매트랩

 

 2.   opencv

 

 

Opencv matlab을 이용하여 이미지의 회전을 하였습니다. 회전은 반시계방향으로 45도를 회전하였습니다. 회전 후의 이미지는 두 opencv matlab은 차이가 있었습니다. 눈으로 봐도 명확히 알 수 있던 것이 opencv를 이용하여 이미지는 사진의 가장자리는 깨끗이 나온 것을 알 수 있습니다. 허나 matlab의 경우에는 aliasing 이 발생한다는 것을 알 수 있었습니다. 이는 설정에 따른 차이때문입니다. opencv에서는 cv2DRotationMatrix()를 이용하였습니다.

매트랩의 경우에는 imrotate()를 사용하였습니다.

Imrotate( A, angle ) <- A : image,

  • fft -> ifft

  • 매트랩 코드

1
2
3
4
5
ca=imread('Matlab_Image/lenna.jpg');
%ca = rgb2gray(ca);
ca_F=fft2(double(ca));
ca_FI=ifft2(ca_F);
subplot(1,2,1),imshow(ca),subplot(1,2,2),imshow(ca_FI,[]);
cs

 

  • opencv 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <stdio.h>
#include <opencv2/core/core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;
 
int main()
{
    Mat I = imread("lenna.jpg", CV_LOAD_IMAGE_GRAYSCALE);
    if (I.empty())
    return -1;
 
    Mat padded;                            //expand input image to optimal size
    int m = getOptimalDFTSize(I.rows);
    int n = getOptimalDFTSize(I.cols); // on the border add zero values
    copyMakeBorder(I, padded, 0, m - I.rows, 0, n - I.cols, BORDER_CONSTANT, Scalar::all(0));
 
    Mat planes[] = { Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F) };
    Mat complexI;
    merge(planes, 2, complexI);         // Add to the expanded another plane with zeros
 
    dft(complexI, complexI);            // this way the result may fit in the source matrix
 
    // compute the magnitude and switch to logarithmic scale
    // => log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
    split(complexI, planes);                   // planes[0= Re(DFT(I), planes[1= Im(DFT(I))
 
    magnitude(planes[0], planes[1], planes[0]);// planes[0= magnitude
    Mat magI = planes[0];
 
    magI += Scalar::all(1);                    // switch to logarithmic scale
    log(magI, magI);
 
    // crop the spectrum, if it has an odd number of rows or columns
    magI = magI(Rect(00, magI.cols & -2, magI.rows & -2));
 
    // rearrange the quadrants of Fourier image  so that the origin is at the image center
    int cx = magI.cols / 2;
    int cy = magI.rows / 2;
 
    Mat q0(magI, Rect(00, cx, cy));   // Top-Left - Create a ROI per quadrant
    Mat q1(magI, Rect(cx, 0, cx, cy));  // Top-Right
    Mat q2(magI, Rect(0, cy, cx, cy));  // Bottom-Left
    Mat q3(magI, Rect(cx, cy, cx, cy)); // Bottom-Right
 
    Mat tmp;                           // swap quadrants (Top-Left with Bottom-Right)
    q0.copyTo(tmp);
    q3.copyTo(q0);
    tmp.copyTo(q3);
 
    q1.copyTo(tmp);                    // swap quadrant (Top-Right with Bottom-Left)
    q2.copyTo(q1);
    tmp.copyTo(q2);
 
 
    normalize(magI, magI, 01, CV_MINMAX); // Transform the matrix with float values into a
    //normalize(phaseVals, phaseVals, 01, CV_MINMAX);
    // viewable image form (float between values 0 and 1).
 
    imshow("Input Image", I);    // Show the result
    imshow("Spectrum Magnitude", magI);
    //waitKey();
 
    //calculating the idft
    cv::Mat inverseTransform;
    cv::dft(complexI, inverseTransform, cv::DFT_INVERSE | cv::DFT_REAL_OUTPUT);
    normalize(inverseTransform, inverseTransform, 01, CV_MINMAX);
    imshow("Reconstructed", inverseTransform);
    waitKey();
 
    return 0;

cs

 

  • 결과 비교

    1. 매트랩

2.   opencv

 

 

  • Gaussian

  •  매트랩 코드

1
2
3
4
5
6
7
8
9
10
11
tic
 
origin = imread('engineer.tif');
noise_img = imnoise(origin,'gaussian',0,0.02);
filt = fspecial('average',[5,5]);
result = filter2(filt,noise_img);
 
imshow(noise_img);
figure(),imshow(result/255);
 
toc
cs
  • opencv 코드

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <time.h>
 
 
IplImage* GaussianNoiseCreate(IplImage *img, int std);
 
>> 가우시안 노이즈를 생성하는 함수의 프로토타입 선언
 
void main() {
    clock_t start, end;
    start = clock();    
    double result;
    
    IplImage *srcImage = cvLoadImage("engineer.tif"-1);
>> 가우시안 노이즈를 입히고 제거하기 위해서 이미지를 불러옵니다.
>> cvLoadImage(“원하는 이미지파일명”,-1);로 Load합니다.
    
 
    //가우시안 잡음 이미지 생성
    //가우시안 잡음 : 가우시안 밀도 함수를 갖는 잡음 (표준편차가 클수록 잡음이 많이 포함됨)
    IplImage *noiseImage = GaussianNoiseCreate(srcImage, 20);
 
>> 작성하는 GaussinNoiseCreate 함수를 통해 원본이미지를 Gaussian 노이즈를 입힌다. 이때 두번째 파라미터 값인 표준편차가 클수록 많은 양의 노이즈를 씌워줄수 있다.
>> srcImage에 가우시안 노이즈를 발생시켜서 noiseImage에 넣어준다.
 
    IplImage* resultImage = cvCreateImage(cvGetSize(noiseImage), IPL_DEPTH_8U, 1);
 
    cvSmooth(noiseImage, resultImage, CV_BLUR, 55);
 
>> 가우시안 노이즈를 평균 필터링을 통해 제거한다 , 필터의 크기는 5x5로 설정되었으며, 노이즈의 양이 많으면 더 큰 크기의 필터의 사용이 필요하며, 수행속도가 느려진다.반대로 노이즈의 크기가 작으면 작은 크기의 필터의 사용이 필요하며, 수행속도가 빨라진다. 따라서 노이즈의 크기를 보고서 알맞은 필터크기를 선정해주는 것이 중요하다. 
 
    end = clock();
    result = (double)(end - start);
    printf("수행시간은 %f초입니다.", result/1000);
    //create window
    cvNamedWindow("source", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("remove", CV_WINDOW_AUTOSIZE);
    //show image
    cvShowImage("source", noiseImage);
    cvShowImage("remove", resultImage);
 
    cvWaitKey(0);
 
    //release image
    cvReleaseImage(&noiseImage);
    cvReleaseImage(&resultImage);    
}
 
//가우시안 잡음 생성 함수
 
IplImage* GaussianNoiseCreate(IplImage *img, int std) {
    int height = img->height;
    int width = img->width;
    int step = img->widthStep;
    uchar* data = (uchar*)img->imageData;
 
    int imgSize = width * height *img->nChannels;
    time_t nowTime;
    srand(time(&nowTime));
 
    int r1, r2;
    double random1, random2, normal, stdNormal, tmp;
    do {
 
        r1 = rand() % width;
        r2 = rand() % height;
 
>> 가우시안 잡음 생성 함수에서 r1과 r2는 이미지에서 노이즈를 발생시킬 위치를 랜덤으로 정하는 것이다.
 
 
        random1 = (double)rand() / RAND_MAX;
        random2 = (double)rand() / RAND_MAX;
 
        stdNormal = sqrt(-2.0 * log(random1)) * cos(2 * 3.14159 * random2);
 
        normal = std * stdNormal;
 
>> std는 표준편차로 아래 if문을 통해 데이터 값의 범위를 0~255범위의 임의의 값으로 만들 때 사용한다.
 
        int index = r1 * step + r2;
        if (index >= imgSize) {
            index = imgSize - 1;
        }
 
        tmp = data[index] + normal;
 
        if (tmp < 0) { data[index] = 0; }
        else if (tmp > 255) { data[index] = 255; }
        else { data[index] = (unsigned char)tmp; }
 
        imgSize--;
    } while (imgSize > 0);
 
    return img;
}
cs
  • 결과비교 

    1. 매트랩

 

2.   opencv

 

검정색 출력창은 visual Open-CV로 가우시안 노이즈 생성 및 제거를 수행했을때의 시간 이고 하얀색 출력창은 Matlab에서 가우시안 노이즈 생성 및 제거를 수행했을때의 시간이다. Open-CVMatlab의 성능은 사람의 눈으로 구분하기에는 큰 차이를 구별할 수가 없는 수준이다.

하지만 수행시간에는 차이를 보였다. 0.4초정도가 Open-CV로 처리하였을 때 더빠른 속도처리를 볼수있었다.

또한 평균필터링을 통해서 노이즈 제거한 이미지에서 노이즈가 제거되었지만 노이즈 뿐만 아니라 원이미지의 성분도 잃어버려서 원본이미지와는 조금의 차이가 보인다.

이것은 Imgae Enhancement를 적용하여서 원이미지와 비슷하게 만들어주는 기법이 필요해보인다.

 

  • histogram equalization 

  •  매트랩 코드

  • opencv 코드

 

 

  •  결과비교

    1. opencv

2.   매트랩

 

 

  • Canny edge

  • 매트랩 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Origin_image=imread('eye.tif');
BW1 = edge(Origin_image,'Canny');
imshow(BW1);      title("Canny");
 
%% color
 
이 프로그램은 원본 이미지를 YCbCr 색 공간으로 변환하여 컬러 이미지의 가장자리를 찾습니다.
%eye.tif
%susan.tif
 
img=imread('susan.tif');
[x y z]=size(img);
if z==1
    rslt=edge(img,'canny');
elseif z==3
    img1=rgb2ycbcr(img);
    dx1=edge(img1(:,:,1),'canny');
    dx1=(dx1*256);
    img2(:,:,1)=dx1;
    img2(:,:,2)=img1(:,:,2);
    img2(:,:,3)=img1(:,:,3);
rslt=ycbcr2rgb(uint8(img2));
end
R=rslt;
imshow(R);      title("Canny");
cs
  • opencv 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv/cv.h"
#include <stdlib.h>
#include <stdio.h>
#include<time.h>
 
using namespace std;
 
void main()
{
    clock_t start, end;
    double result;
    IplImage* srcImage = cvLoadImage("susan.tif", CV_LOAD_IMAGE_GRAYSCALE);
    IplImage* cannyImage1 = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 1);
 
    if (srcImage == NULL)
        return;
    cvNamedWindow("cannyImage1", CV_WINDOW_AUTOSIZE); //window 화면 뛰우기
    start = clock();                
    cvCanny(srcImage, cannyImage1, 501003);
    end = clock();
    cvShowImage("CannyImage1", cannyImage1);
    
    cvWaitKey(0); 
    cvDestroyAllWindows();
    cvReleaseImage(&cannyImage1);
    
    result=(double)(end - start);
    printf("%f", result);
}
cs
  • 결과비교 

    1. 매트랩

 

 

                     2.   opencv

 

  • Salt & pepper noise

  •  매트랩 코드

1
2
3
4
5
6
7
8
9
tic
img = imread('cameraman.tif');
subplot(1,2,1);
imshow(img);
title('Original image')
subplot(1,2,2);
imshow(imnoise(img,'salt & pepper'));
title('salt & pepper');
toc
cs
  • opencv 코드 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include<opencv2/opencv.hpp>
#include <iostream>
 
using namespace std;
using namespace cv;
 
void salt(cv::Mat &image, int n);
 
int main()
{
   cv::Mat image = cv::imread("house.jpg");
   salt(image, 1000);
   cv::namedWindow("my image");
   cv::imshow("my image", image);
   cv::waitKey(5000);
   return 1;
}
 
void salt(cv::Mat &image, int n) {
   for (int k = 0; k < n; k++) {
      int i = rand() % image.cols;
      int j = rand() % image.rows;
 
      if (image.channels() == 1) {
         image.at<uchar>(j, i) = 255;
      }
      else if (image.channels() == 3) {
         image.at<cv::Vec3b>(j, i)[0= 255;
         image.at<cv::Vec3b>(j, i)[1= 255;
         image.at<cv::Vec3b>(j, i)[2= 255;
      }
   }
}
cs
  • 결과비교

    1. 매트랩

 

                       2. opencv

같은 알고리즘을 수행한 결과 opencv가 매트랩보다 노이즈가 덜 한 것을 관찰할 수 있었습니다.

매트랩의 salt & pepper noise구현은 검은색과 흰색의 노이즈가 보이지만

opencv로 만들어본 nosie는 흰색의 노이즈만 관찰되었습니다.

  • sobel edge detect

  • 매트랩 코드

1
2
3
4
5
6
7
8
9
tic
og = imread('cameraman.tif');
subplot(1,2,1);
imshow(og);
title('Original image')
subplot(1,2,2);
imshow(edge(og,'sobel'));
title('sobel edge');
toc
cs
  • opencv 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "iostream"
#include <time.h>
#include <stdio.h>
using namespace cv;
using namespace std;
void main()
 
{
    clock_t start, end;
    start = clock();
    double result;
    Mat src1;
    src1 = imread("engineer.tif", CV_LOAD_IMAGE_COLOR);
    namedWindow("Original image", CV_WINDOW_AUTOSIZE);
    imshow("Original image", src1);
 
    Mat grey;
    cvtColor(src1, grey, CV_BGR2GRAY); // 그레이 영상으로 변환
    Mat sobelx, sobely;
    Sobel(grey, sobelx, CV_32F, 10); // Sobel 엣지 검출
    Sobel(grey, sobely, CV_32F, 01);
 
    namedWindow("vertical edge", CV_WINDOW_AUTOSIZE);
    imshow("vertical edge", sobelx);
    namedWindow("horizontal edge", CV_WINDOW_AUTOSIZE);
    imshow("horizontal edge", sobely);
 
    end = clock();        
    result = (double)(end - start);
    printf("time %f", result / 1000);
 
    waitKey(0);
 
}
cs
  • 결과 비교

    1. 매트랩

 

 경과시간 : 0.350917 sec

 

 2. opencv

 

 경과시간 : 0.108000 sec

 

matlab 같이 opencv 이용해 sobel edge detect 수행한 결과

opencv 이용한 것이 수행시간이 줄었습니다.

 

  • LOG(Laplacian of gaussian) 으로 엣지 검출

  • 매트랩 코드

1
2
3
4
5
6
7
8
I=imread('bacteria.tif');
 
figure(1);imshow(I);
 
BW=edge(I,'log'); 
LoG(가우스-라플라시안) 필터를 사용하여 I를 필터링한 후 영점교차를 찾아서 경계를 찾습니다.
 
figure(2);imshow(BW);
cs
  • opencv 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <opencv2\opencv.hpp>
#include <time.h>
#include <cstdio>
 
using namespace cv;
using namespace std;
 
int main() {
 
    clock_t beginend;
 
    Mat image = imread("bacteria.tif",0);
 
    CV_Assert(image.data);
 
    double sigma = 1.4;
    
    Mat dst1, gaus_img;
    // 시간측정 시작. 
    begin = clock();
 
    GaussianBlur(image, gaus_img, Size(99), sigma, sigma);
 
//가우시안 필터 씌우기
 
    Laplacian(gaus_img, dst1, -15);
 
//Laplacian을 통해 이차 미분을 할 수 있고, 따라서 edge를 검출 할 수 있다.
 
 
    end = clock();
 
    imshow("image", image);
    imshow("dst2- LOG_OpenCV", dst1);
    
 
 
    cout << "수행시간(초) : " << (double)(end - begin/ CLOCKS_PER_SEC << endl;
    waitKey();
 
 
    return 0;
 
}
cs
  • 결과비교

    1. 매트랩

 

2.   opencv

이번에는 특이하게 opencv의 수행시간이 더 걸렸는데 매트랩결과와 비교해보았을 때, opencv의 윤곽선이 더 진합니다.

Opencv는 비교적 디테일이 남아있는 모습을 보여줍니다.

이것을 없애고 싶다면 가우시안 필터를 더 키우면 될 것입니다.

  • DCT -> IDCT

  • 매트랩 코드

1
2
3
4
5
6
7
8
9
ca=imread('house.jpg');
ca = rgb2gray(ca);
ca_F=dct2(double(ca));
ca_F1=idct2(ca_F);
ca_F = uint8(ca_F);
ca_F1 = uint8(ca_F1);
subplot(1,3,1),imshow(ca),title('original image');
subplot(1,3,2),imshow(ca_F),title('DCT image');
subplot(1,3,3),imshow(ca_F1),title('IDCT image');
cs
  • opencv 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <stdlib.h>
#include <stdio.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
 
using namespace cv;
using namespace std;
 
int main()
{
    Mat image = imread("house.jpg"0); // grayscale
    Mat fimage;
    image.convertTo(fimage, CV_32F, 1.0 / 255);
    imshow("Original Image", image);
    Mat dimage;
    dct(fimage, dimage);
    
    imshow("DCT Image", dimage);
 
    Mat dimage2;
    dct(dimage, dimage2, DCT_INVERSE);
 
 
    imshow("IDCT", dimage2);
 
    waitKey();
 
 
    return 0;
}
cs

 

먼저 컬러 이미지 ‘house.jpg’gray이미지로 변환하고 dct2 함수를 이용해서 gray이미지를 이산코사인 변환 하고, idct2 함수를 이용해서 원본 이미지로 복원합니다.

  • 결과비교

    1. 매트랩

 

2.   opencv

OpenCV로 했을 때와 Matlab으로 했을 때 IDCT를 비교해보면 두 이미지의 차이가 심하지 않은 걸 볼 수 있습니다.

원본 이미지와 복원한 이미지를 비교해 보아도 달라진 점을 찾을 수 없는 것으로 보아 DCT의 손실율이 매우 작은 것을 확인 할 수 있었습니다.

'영상처리 실습' 카테고리의 다른 글

matlab wavelets toolbox  (0) 2018.12.06
노이즈 복원&엣지 검출 실습  (0) 2018.11.20

+ Recent posts