에지검출하기1

1차미분을 이용한 cvSobel() 함수이용



c++)

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
#include <opencv/cv.h>
#include <opencv/highgui.h>
 
 
void main() {
    IplImage* srcImage = cvLoadImage("D:/study/testimage3.jpg"-1);
    IplImage* edgeImage = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 3);
 
    
    //에지(edge) : 밝기가 낮은값에서 높은값으로, 높은값에서 낮은값으로 변화하는 경계에 해당되는 부분
    //cvSobel(원본이미지, 에지이미지, x방향 미분, y방향 미분, 커널크기) : 에지검출함수
    cvSobel(srcImage, edgeImage, 113);
 
 
    cvNamedWindow("source", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("edge", CV_WINDOW_AUTOSIZE);
 
    cvShowImage("source", srcImage);
    cvShowImage("edge", edgeImage);
 
    cvWaitKey(0);
 
    cvReleaseImage(&srcImage);
    cvReleaseImage(&edgeImage);
}
cs



결과




임펄스 잡음 제거하기 (중앙값 필터링 사용)



c++)

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
#include <opencv/cv.h>
#include <opencv/highgui.h>
 
 
void main() {
    IplImage* noiseImage = cvLoadImage("D:/study/impulseimage.jpg"-1);
    IplImage* resultImage = cvCreateImage(cvGetSize(noiseImage), IPL_DEPTH_8U, 1);
 
 
    //임펄스 잡음 제거 : 중앙값 필터링 사용
    //잡음이 남아있을 경우 반복하여 필터링 한다
    cvSmooth(noiseImage, resultImage, CV_MEDIAN, 33);
 
 
    //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);
}
cs



결과



잡음 제거하기 (평균필터링 사용)



c++)

가우시안 잡음 제거는 평균필터링을 사용하여 제거한다

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
#include <opencv/cv.h>
#include <opencv/highgui.h>
 
 
void main() {
    IplImage* noiseImage = cvLoadImage("D:/study/gaussianimage.jpg"-1);
    IplImage* resultImage = cvCreateImage(cvGetSize(noiseImage), IPL_DEPTH_8U, 1);
 
 
    //가우시안 잡음 제거 : 평균필터링 이용
    //마스크의 평균값을 이용한다
    cvSmooth(noiseImage, resultImage, CV_BLUR, 33);
 
    
    //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);
}
 
cs



결과




잡음이 있는 이미지 생성하기 (임펄스 잡음)

임펄스 잡음 : 흰색과 검은색을 갖는 잡음



c++)

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
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <time.h>
 
 
IplImage* ImpulseNoiseCreate(IplImage *img, double noiseRate);
 
 
void main() {
    IplImage* srcImage = cvLoadImage("D:/study/Lena_gray.jpg"-1);
 
 
    IplImage* impulseImage = ImpulseNoiseCreate(srcImage, 0.2);
 
 
    //create window
    cvNamedWindow("impulse", CV_WINDOW_AUTOSIZE);
    //show image
    cvShowImage("impulse", impulseImage);
 
    cvWaitKey(0);
 
    //release image
    cvReleaseImage(&impulseImage);
}
 
//임펄스 잡음 이미지 생성
//임펄스 잡음 : 흰색과 검은색을 갖는 잡음
IplImage* ImpulseNoiseCreate(IplImage *img, double noiseRate) {
    int height = img->height;
    int width = img->width;
    int step = img->widthStep;
    uchar* data = (uchar*)img->imageData;
 
 
    int rand1, rand2;
    int imgSize = width * height;
    int numOfNoise = (int)(imgSize * noiseRate / 2);
    time_t nowTime;
    srand(time(&nowTime));
 
    //랜덤으로 검은색으로 잡음을 준다
    for (int i = 0; i < numOfNoise; i++) {
        rand1 = rand() % width;
        rand2 = rand() % height;
        
        int index = rand1*step + rand2;
        if (index >= imgSize) {
            index = imgSize - 1;
        }
        data[index] = 0;
    }
 
    //랜덤으로 하얀색으로 잡음을 준다
    for (int i = 0; i < numOfNoise; i++) {
        rand1 = rand() % width;
        rand2 = rand() % height;
 
        int index = rand1*step + rand2;
        if (index >= imgSize) {
            index = imgSize - 1;
        }
        data[index] = 255;
    }
 
    return img;
}
cs



결과



잡음이 있는 이미지 생성하기 (가우시안 잡음)

가우시안 잡음 : 가우시안 밀도 함수를 갖는 잡음



c++)

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
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <time.h>
 
 
IplImage* GaussianNoiseCreate(IplImage *img, int std);
 
void main() {
    IplImage *srcImage = cvLoadImage("D:/study/testimage.jpg"-1);
 
 
    //가우시안 잡음 이미지 생성
    //가우시안 잡음 : 가우시안 밀도 함수를 갖는 잡음 (표준편차가 클수록 잡음이 많이 포함됨)
    IplImage *noiseImage = GaussianNoiseCreate(srcImage, 60);
 
 
    //create a window 
    cvNamedWindow("gaussian noise", CV_WINDOW_AUTOSIZE);
    //show image
    cvShowImage("gaussian noise", noiseImage);
 
    cvWaitKey(0);
 
    //release image
    cvReleaseImage(&noiseImage);
}
 
 
//가우시안 잡음 생성 함수
//Box-Muller(통계학의 변수변환 방법) 사용
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;
 
        random1 = (double)rand() / RAND_MAX;
        random2 = (double)rand() / RAND_MAX;
 
        stdNormal = sqrt(-2.0 * log(random1)) * cos(2 * 3.14159 * random2);
 
        normal = std * stdNormal;
 
        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



결과



이미지 샤프닝(세세한 부분을 강조) 하기



c++)

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
#include <opencv/cv.h>
#include <opencv/highgui.h>
 
 
void main() {
    IplImage *srcImage = cvLoadImage("D:/study/blurimage.jpg"-1);
    IplImage *rstImage1 = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 3);
    IplImage *rstImage2 = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 3);
    IplImage *rstImage3 = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 3);
 
 
    //영상 샤프닝 : 영상의 세세한 부분을 더욱 강조하여 흐려서 판독이 잘 안되는 영상을 더욱 선명하게 하는것
    //샤프닝 마스크의 모든 계수의 합은 1이다
    double mask1[3][3= { 
        {1-21}, 
        { -25-2 }, 
        { 1-21 } };
    double mask2[3][3= { 
        { 0-10 },
        { -15-1 },
        { 0-10 } };
    double mask3[3][3= { 
        { -1-1-1 },
        { -19-1 },
        { -1-1-1 } };
 
 
    //cvMat(행의수, 열의수, 행렬원소의 형태, 데이터) : 행렬생성
    //행렬원소의 형태 : CV_<비트수>(S|U|F)C<채널수>
    CvMat kernel1 = cvMat(33, CV_64FC1, mask1);
    CvMat kernel2 = cvMat(33, CV_64FC1, mask2);
    CvMat kernel3 = cvMat(33, CV_64FC1, mask3);
 
    //cvFilter2D(원본 이미지, 결과 이미지, 마스크 행렬) : 사용자 정의한 마스크로 이미지 컨벌루션
    //ps. 마스크 행렬 데이터들은 1채널 실수형이어야 한다
    cvFilter2D(srcImage, rstImage1, &kernel1);
    cvFilter2D(srcImage, rstImage2, &kernel2);
    cvFilter2D(srcImage, rstImage3, &kernel3);
 
 
 
    //create window
    cvNamedWindow("source image", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("sharp1 image", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("sharp2 image", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("sharp3 image", CV_WINDOW_AUTOSIZE);
    //show window
    cvShowImage("source image", srcImage);
    cvShowImage("sharp1 image", rstImage1);
    cvShowImage("sharp2 image", rstImage2);
    cvShowImage("sharp3 image", rstImage3);
 
    cvWaitKey(0);
 
    //release image
    cvReleaseImage(&srcImage);
    cvReleaseImage(&rstImage1);
    cvReleaseImage(&rstImage2);
    cvReleaseImage(&rstImage3);
}
cs



결과



이미지 가우시안 필터링 하기



c++)

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
#include <opencv/cv.h>
#include <opencv/highgui.h>
 
 
void main() {
    IplImage *srcImage = cvLoadImage("D:/study/testimage.jpg"-1);
    IplImage *rstImage1 = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 3);
    IplImage *rstImage2 = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 3);
 
 
 
    //cvSmooth : 이미지 스무딩(=블러링) 함수
    //cvSmooth(원본이미지, 결과이미지, 스무딩 형태, 마스크가로크기, 마스크 세로크기, 가우시안 마스크인 경우 표준편차1, 표준편차2)
    //스무딩 형태
    //CV_BLUR :  단순 블러링(param1 x param2 영역의 평균값을 이용한 블러링)
    //CV_GAUSSIAN : 가우시안 블러링
    //CV_MEDIAN : 중앙값 블러링(param1 x param2 영역의 중앙값을 이용한 블러링)
    cvSmooth(srcImage, rstImage1, CV_GAUSSIAN, 5540);    //마스크 크기가 5x5이며 표준편차가 2인 경우
    cvSmooth(srcImage, rstImage2, CV_GAUSSIAN, 5580);
    //ps. 가우시안 필터링은 표준편차가 클수록 더 흐릿해진다
 
 
 
    //create window
    cvNamedWindow("source image", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("sigma4 image", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("sigma8 image", CV_WINDOW_AUTOSIZE);
    //show window
    cvShowImage("source image", srcImage);
    cvShowImage("sigma4 image", rstImage1);
    cvShowImage("sigma8 image", rstImage2);
 
    cvWaitKey(0);
 
    //release image
    cvReleaseImage(&srcImage);
    cvReleaseImage(&rstImage1);
    cvReleaseImage(&rstImage2);
}
cs



결과




이미지 중앙값 필터링 하기



c++)

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
#include <opencv/cv.h>
#include <opencv/highgui.h>
 
 
void main() {
    IplImage *srcImage = cvLoadImage("D:/study/testimage.jpg"-1);
    IplImage *rstImage7x7 = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 3);
    IplImage *rstImage13x13 = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 3);
 
 
 
    //cvSmooth : 이미지 스무딩(=블러링) 함수
    //cvSmooth(원본이미지, 결과이미지, 스무딩 형태, 마스크가로크기, 마스크 세로크기, 가우시안 마스크인 경우 표준편차1, 표준편차2)
    //스무딩 형태
    //CV_BLUR :  단순 블러링(param1 x param2 영역의 평균값을 이용한 블러링)
    //CV_GAUSSIAN : 가우시안 블러링
    //CV_MEDIAN : 중앙값 블러링(param1 x param2 영역의 중앙값을 이용한 블러링)
    cvSmooth(srcImage, rstImage7x7, CV_MEDIAN, 7700);    //중앙값 : 마스크 영역의 픽셀값을 오름차순하여 중앙에 있는 값
    cvSmooth(srcImage, rstImage13x13, CV_MEDIAN, 131300);
 
 
 
    //create window
    cvNamedWindow("source image", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("7x7 image", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("13x13 image", CV_WINDOW_AUTOSIZE);
    //show window
    cvShowImage("source image", srcImage);
    cvShowImage("7x7 image", rstImage7x7);
    cvShowImage("13x13 image", rstImage13x13);
 
    cvWaitKey(0);
 
    //release image
    cvReleaseImage(&srcImage);
    cvReleaseImage(&rstImage7x7);
    cvReleaseImage(&rstImage13x13);
}
cs



결과



사용자가 지정한 마스크로 컨벌루션하기

컨벌루션 : 가중치를 갖는 마스크를 이용해 영상처리를 하는것



c++)

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
#include <opencv/cv.h>
#include <opencv/highgui.h>
 
 
void main() {
    IplImage *srcImage = cvLoadImage("D:/study/testimage.jpg"-1);
    IplImage *resultImage = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 3);
 
    double maskData[7][7= { { 1.0 / 491.0 / 491.0 / 491.0 / 491.0 / 491.0 / 491.0 / 49 },
                              { 1.0 / 491.0 / 491.0 / 491.0 / 491.0 / 491.0 / 491.0 / 49 },
                              { 1.0 / 491.0 / 491.0 / 491.0 / 491.0 / 491.0 / 491.0 / 49 },
                              { 1.0 / 491.0 / 491.0 / 491.0 / 491.0 / 491.0 / 491.0 / 49 },
                              { 1.0 / 491.0 / 491.0 / 491.0 / 491.0 / 491.0 / 491.0 / 49 },
                              { 1.0 / 491.0 / 491.0 / 491.0 / 491.0 / 491.0 / 491.0 / 49 },
                              { 1.0 / 491.0 / 491.0 / 491.0 / 491.0 / 491.0 / 491.0 / 49 }};
    //cvMat(행의수, 열의수, 행렬원소의 형태, 데이터) : 행렬생성
    //행렬원소의 형태 : CV_<비트수>(S|U|F)C<채널수>
    CvMat kernel = cvMat(77, CV_64FC1, maskData);
    
    //cvFilter2D(원본 이미지, 결과 이미지, 마스크 행렬) : 사용자 정의한 마스크로 이미지 블러링
    //ps. 마스크 행렬 데이터들은 1채널 실수형이어야 한다
    cvFilter2D(srcImage, resultImage, &kernel);
 
 
    //create window
    cvNamedWindow("source image", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("7x7 image", CV_WINDOW_AUTOSIZE);
 
    //show window
    cvShowImage("source image", srcImage);
    cvShowImage("7x7 image", resultImage);
 
    cvWaitKey(0);
 
    cvReleaseImage(&srcImage);
    cvReleaseImage(&resultImage);
}
 
cs



결과




이미지 블러링 하기



c++)

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
#include <opencv/cv.h>
#include <opencv/highgui.h>
 
 
void main() {
    IplImage *srcImage = cvLoadImage("D:/study/testimage.jpg"-1);
    IplImage *resultImage3x3 = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 3);
    IplImage *resultImage5x5 = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 3);
 
    //cvSmooth : 이미지 스무딩(=블러링) 함수
    //cvSmooth(원본이미지, 결과이미지, 스무딩 형태, 마스크가로크기, 마스크 세로크기, 가우시안 마스크인 경우 표준편차1, 표준편차2)
    //스무딩 형태
    //CV_BLUR :  단순 블러링(param1 x param2 영역의 평균값을 이용한 블러링)
    //CV_GAUSSIAN : 가우시안 블러링
    //CV_MEDIAN : 중앙값 블러링(param1 x param2 영역의 중앙값을 이용한 블러링)
    cvSmooth(srcImage, resultImage3x3, CV_BLUR, 3300);
    cvSmooth(srcImage, resultImage5x5, CV_BLUR, 5500);
 
 
    //create window
    cvNamedWindow("source image", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("3x3 image", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("5x5 image", CV_WINDOW_AUTOSIZE);
 
    //show window
    cvShowImage("source image", srcImage);
    cvShowImage("3x3 image", resultImage3x3);
    cvShowImage("5x5 image", resultImage5x5);
 
    cvWaitKey(0);
 
    cvReleaseImage(&srcImage);
    cvReleaseImage(&resultImage3x3);
    cvReleaseImage(&resultImage5x5);
}
 
cs



결과

3x3마스크와 5x5마스크로 블러링된 이미지



+ Recent posts