Erosion(침식) : 검은색 픽셀을 확장시켜주어 흰색을 침식한다. 물체끼리의 구분에 유용
Dilation(확장) : 흰색 픽셀을 확장시켜 검은색을 침식한다. 물체를 명확하게 만듬
결과에서 보면 확장을 2번하였을 경우 물체가 흰색으로 물들며 물체가 선명해지는 것을 볼 수 있고,
침식을 2번하였을 경우 물체사이의 검은색 픽셀이 확장되며 물체가 구분되는 것을 볼 수 있다.
검은색을 늘린 후 (침식) 흰색을 늘리면 (확장) opening 연산(독립영역 찾기)이라 하고 반대의 경우 closing 연산(잡음 제거)이라 한다. 여기서 결과는 closing 연산이다.
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
#include <opencv\cv.h>
#include <opencv\highgui.h>
void main()
{
IplImage* image = 0; // image 선언
image = cvLoadImage("coins.jpg", 1); //img.jpg파일을 불러옴 1은 컬러로 받아옴, 0은 흑백으로 받아옴(rgb가 없음)
int imageRatio = 1;
CvSize size = cvSize(image->width*imageRatio, image->height*imageRatio);
IplImage *tmpImg = cvCreateImage(size,IPL_DEPTH_8U,3);
IplImage *tmpImg2 = cvCreateImage(size,IPL_DEPTH_8U,3);
int width = image->width;
int height = image->height;
int index = image->widthStep;
int avg;
int thd = 120;
for(int i=0; i<height;i++){
for(int j=0; j<width; j++){
//gray scale
int index2 = i*image->widthStep + j*3;
avg = ((unsigned char)image->imageData[index2+0]+(unsigned char)image->imageData[index2+1]+(unsigned char)image->imageData[index2+2])/3;
//이진화
if(avg > thd) avg = 255;
else avg = 0;
for(int k=0;k<3;k++)
image->imageData[i*index+j*3+k] = avg;
}
}
//생성된 이미지를 검은색으로 만듬
for(int i=0;i<tmpImg->height;i++)
for(int j=0;j<tmpImg->width;j++)
for(int k=0;k<3;k++)
{
tmpImg->imageData[i*tmpImg->widthStep+j*3+k] = image->imageData[i*index+j*3+k];
}
//원본이미지
cvShowImage( "original", image );
//Dilation(팽창)
for(int i=1;i<height-1;i++)
for(int j=1;j<width-1;j++){
if((unsigned char)image->imageData[i*index+j*3] == 255){
for(int ii=-1;ii<2;ii++)
for(int jj=-1;jj<2;jj++)
{
tmpImg->imageData[(i+ii)*tmpImg->widthStep+(j+jj)*3+0] = 255;
tmpImg->imageData[(i+ii)*tmpImg->widthStep+(j+jj)*3+1] = 255;
tmpImg->imageData[(i+ii)*tmpImg->widthStep+(j+jj)*3+2] = 255;
}
}
}
cvShowImage( "Dilation1", tmpImg );
//Dilation
for(int i=1;i<height-1;i++)
for(int j=1;j<width-1;j++){
if((unsigned char)tmpImg->imageData[i*index+j*3] == 255){
for(int ii=-1;ii<2;ii++)
for(int jj=-1;jj<2;jj++)
{
image->imageData[(i+ii)*tmpImg->widthStep+(j+jj)*3+0] = 255;
image->imageData[(i+ii)*tmpImg->widthStep+(j+jj)*3+1] = 255;
image->imageData[(i+ii)*tmpImg->widthStep+(j+jj)*3+2] = 255;
}
}
}
cvShowImage( "Dilation2", image );
//Erosion(침식)
for(int i=1;i<height-1;i++)
for(int j=1;j<width-1;j++){
if((unsigned char)image->imageData[i*index+j*3] == 0){
for(int ii=-1;ii<2;ii++)
for(int jj=-1;jj<2;jj++)
{
tmpImg->imageData[(i+ii)*tmpImg->widthStep+(j+jj)*3+0] = 0;
tmpImg->imageData[(i+ii)*tmpImg->widthStep+(j+jj)*3+1] = 0;
tmpImg->imageData[(i+ii)*tmpImg->widthStep+(j+jj)*3+2] = 0;
}
}
}
cvShowImage( "Erosion1", tmpImg );
//Erosion(침식)
for(int i=1;i<height-1;i++)
for(int j=1;j<width-1;j++){
if((unsigned char)tmpImg->imageData[i*index+j*3] == 0){
for(int ii=-1;ii<2;ii++)
for(int jj=-1;jj<2;jj++)
{
image->imageData[(i+ii)*tmpImg->widthStep+(j+jj)*3+0] = 0;
image->imageData[(i+ii)*tmpImg->widthStep+(j+jj)*3+1] = 0;
image->imageData[(i+ii)*tmpImg->widthStep+(j+jj)*3+2] = 0;
}
}
}
cvShowImage( "Erosion2", image );
cvSaveImage("out.jpg",image);
cvSaveImage("edge.jpg",tmpImg);
cvWaitKey(0); // 사용자의 키 입력을 기다림
}
|
결과

댓글 없음:
댓글 쓰기