05_filtering.py

Download
python 265 lines 7.3 KB
  1"""
  205. ์ด๋ฏธ์ง€ ํ•„ํ„ฐ๋ง
  3- blur, GaussianBlur, medianBlur
  4- bilateralFilter
  5- ์ปค์Šคํ…€ ํ•„ํ„ฐ (filter2D)
  6- ์ƒคํ”„๋‹
  7"""
  8
  9import cv2
 10import numpy as np
 11
 12
 13def create_noisy_image():
 14    """๋…ธ์ด์ฆˆ๊ฐ€ ์žˆ๋Š” ํ…Œ์ŠคํŠธ ์ด๋ฏธ์ง€ ์ƒ์„ฑ"""
 15    img = np.zeros((300, 400, 3), dtype=np.uint8)
 16    img[:] = [200, 200, 200]
 17
 18    # ๋„ํ˜• ๊ทธ๋ฆฌ๊ธฐ
 19    cv2.rectangle(img, (50, 50), (150, 150), (0, 0, 255), -1)
 20    cv2.circle(img, (300, 150), 50, (255, 0, 0), -1)
 21    cv2.putText(img, 'Filter', (150, 250), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2)
 22
 23    # ๊ฐ€์šฐ์‹œ์•ˆ ๋…ธ์ด์ฆˆ ์ถ”๊ฐ€
 24    noise = np.random.normal(0, 25, img.shape).astype(np.int16)
 25    noisy = np.clip(img.astype(np.int16) + noise, 0, 255).astype(np.uint8)
 26
 27    return img, noisy
 28
 29
 30def create_salt_pepper_noise(img):
 31    """์†Œ๊ธˆ-ํ›„์ถ” ๋…ธ์ด์ฆˆ ์ถ”๊ฐ€"""
 32    noisy = img.copy()
 33    # ์†Œ๊ธˆ (ํฐ์ƒ‰)
 34    salt = np.random.random(img.shape[:2]) < 0.02
 35    noisy[salt] = 255
 36    # ํ›„์ถ” (๊ฒ€์ •)
 37    pepper = np.random.random(img.shape[:2]) < 0.02
 38    noisy[pepper] = 0
 39    return noisy
 40
 41
 42def blur_demo():
 43    """๋ธ”๋Ÿฌ ํ•„ํ„ฐ ๋ฐ๋ชจ"""
 44    print("=" * 50)
 45    print("๋ธ”๋Ÿฌ ํ•„ํ„ฐ")
 46    print("=" * 50)
 47
 48    original, noisy = create_noisy_image()
 49
 50    # ํ‰๊ท  ๋ธ”๋Ÿฌ (Box Filter)
 51    blur_3x3 = cv2.blur(noisy, (3, 3))
 52    blur_5x5 = cv2.blur(noisy, (5, 5))
 53    blur_7x7 = cv2.blur(noisy, (7, 7))
 54
 55    print("ํ‰๊ท  ๋ธ”๋Ÿฌ (Box Filter):")
 56    print("  - ๋ชจ๋“  ํ”ฝ์…€์— ๋™์ผํ•œ ๊ฐ€์ค‘์น˜")
 57    print("  - ์ปค๋„ ํฌ๊ธฐ๊ฐ€ ํด์ˆ˜๋ก ๋” ํ๋ ค์ง")
 58
 59    cv2.imwrite('original.jpg', original)
 60    cv2.imwrite('noisy.jpg', noisy)
 61    cv2.imwrite('blur_3x3.jpg', blur_3x3)
 62    cv2.imwrite('blur_5x5.jpg', blur_5x5)
 63    cv2.imwrite('blur_7x7.jpg', blur_7x7)
 64
 65
 66def gaussian_blur_demo():
 67    """๊ฐ€์šฐ์‹œ์•ˆ ๋ธ”๋Ÿฌ ๋ฐ๋ชจ"""
 68    print("\n" + "=" * 50)
 69    print("๊ฐ€์šฐ์‹œ์•ˆ ๋ธ”๋Ÿฌ")
 70    print("=" * 50)
 71
 72    _, noisy = create_noisy_image()
 73
 74    # ๊ฐ€์šฐ์‹œ์•ˆ ๋ธ”๋Ÿฌ
 75    # GaussianBlur(src, ksize, sigmaX)
 76    gauss_3x3 = cv2.GaussianBlur(noisy, (3, 3), 0)
 77    gauss_5x5 = cv2.GaussianBlur(noisy, (5, 5), 0)
 78    gauss_7x7 = cv2.GaussianBlur(noisy, (7, 7), 0)
 79
 80    # sigma ๊ฐ’์— ๋”ฐ๋ฅธ ์ฐจ์ด
 81    gauss_s1 = cv2.GaussianBlur(noisy, (5, 5), 1)
 82    gauss_s3 = cv2.GaussianBlur(noisy, (5, 5), 3)
 83    gauss_s5 = cv2.GaussianBlur(noisy, (5, 5), 5)
 84
 85    print("๊ฐ€์šฐ์‹œ์•ˆ ๋ธ”๋Ÿฌ:")
 86    print("  - ์ค‘์•™์— ๋†’์€ ๊ฐ€์ค‘์น˜, ๊ฐ€์žฅ์ž๋ฆฌ์— ๋‚ฎ์€ ๊ฐ€์ค‘์น˜")
 87    print("  - ์ž์—ฐ์Šค๋Ÿฌ์šด ๋ธ”๋Ÿฌ ํšจ๊ณผ")
 88    print("  - sigma๊ฐ€ ํด์ˆ˜๋ก ๋” ํ๋ ค์ง")
 89
 90    cv2.imwrite('gauss_3x3.jpg', gauss_3x3)
 91    cv2.imwrite('gauss_5x5.jpg', gauss_5x5)
 92    cv2.imwrite('gauss_sigma1.jpg', gauss_s1)
 93    cv2.imwrite('gauss_sigma5.jpg', gauss_s5)
 94
 95
 96def median_blur_demo():
 97    """๋ฏธ๋””์–ธ ๋ธ”๋Ÿฌ ๋ฐ๋ชจ"""
 98    print("\n" + "=" * 50)
 99    print("๋ฏธ๋””์–ธ ๋ธ”๋Ÿฌ")
100    print("=" * 50)
101
102    original, _ = create_noisy_image()
103    sp_noisy = create_salt_pepper_noise(original)
104
105    # ๋ฏธ๋””์–ธ ๋ธ”๋Ÿฌ
106    median_3 = cv2.medianBlur(sp_noisy, 3)
107    median_5 = cv2.medianBlur(sp_noisy, 5)
108    median_7 = cv2.medianBlur(sp_noisy, 7)
109
110    print("๋ฏธ๋””์–ธ ๋ธ”๋Ÿฌ:")
111    print("  - ์ปค๋„ ๋‚ด ์ค‘์•™๊ฐ’ ์‚ฌ์šฉ")
112    print("  - ์†Œ๊ธˆ-ํ›„์ถ” ๋…ธ์ด์ฆˆ ์ œ๊ฑฐ์— ํšจ๊ณผ์ ")
113    print("  - ์—ฃ์ง€ ๋ณด์กด ํšจ๊ณผ")
114
115    cv2.imwrite('salt_pepper_noisy.jpg', sp_noisy)
116    cv2.imwrite('median_3.jpg', median_3)
117    cv2.imwrite('median_5.jpg', median_5)
118
119
120def bilateral_filter_demo():
121    """์–‘๋ฐฉํ–ฅ ํ•„ํ„ฐ ๋ฐ๋ชจ"""
122    print("\n" + "=" * 50)
123    print("์–‘๋ฐฉํ–ฅ ํ•„ํ„ฐ (Bilateral Filter)")
124    print("=" * 50)
125
126    _, noisy = create_noisy_image()
127
128    # ์–‘๋ฐฉํ–ฅ ํ•„ํ„ฐ
129    # bilateralFilter(src, d, sigmaColor, sigmaSpace)
130    # d: ํ•„ํ„ฐ ํฌ๊ธฐ (-1์ด๋ฉด sigmaSpace์—์„œ ์ž๋™ ๊ณ„์‚ฐ)
131    # sigmaColor: ์ƒ‰์ƒ ๊ณต๊ฐ„์—์„œ์˜ ์‹œ๊ทธ๋งˆ
132    # sigmaSpace: ์ขŒํ‘œ ๊ณต๊ฐ„์—์„œ์˜ ์‹œ๊ทธ๋งˆ
133
134    bilateral_1 = cv2.bilateralFilter(noisy, 9, 75, 75)
135    bilateral_2 = cv2.bilateralFilter(noisy, 9, 150, 150)
136    bilateral_3 = cv2.bilateralFilter(noisy, -1, 75, 75)
137
138    print("์–‘๋ฐฉํ–ฅ ํ•„ํ„ฐ:")
139    print("  - ์—ฃ์ง€๋ฅผ ๋ณด์กดํ•˜๋ฉด์„œ ๋…ธ์ด์ฆˆ ์ œ๊ฑฐ")
140    print("  - sigmaColor: ์ƒ‰์ƒ ์ฐจ์ด ํ—ˆ์šฉ ๋ฒ”์œ„")
141    print("  - sigmaSpace: ๊ณต๊ฐ„์  ์˜ํ–ฅ ๋ฒ”์œ„")
142    print("  - ๋‹ค๋ฅธ ํ•„ํ„ฐ๋ณด๋‹ค ๋А๋ฆผ")
143
144    cv2.imwrite('bilateral_75.jpg', bilateral_1)
145    cv2.imwrite('bilateral_150.jpg', bilateral_2)
146
147
148def custom_filter_demo():
149    """์ปค์Šคํ…€ ํ•„ํ„ฐ ๋ฐ๋ชจ"""
150    print("\n" + "=" * 50)
151    print("์ปค์Šคํ…€ ํ•„ํ„ฐ (filter2D)")
152    print("=" * 50)
153
154    original, _ = create_noisy_image()
155
156    # ํ‰๊ท  ํ•„ํ„ฐ ์ปค๋„
157    kernel_avg = np.ones((3, 3), dtype=np.float32) / 9
158    avg_filtered = cv2.filter2D(original, -1, kernel_avg)
159
160    # ์ƒคํ”„๋‹ ์ปค๋„
161    kernel_sharpen = np.array([
162        [0, -1, 0],
163        [-1, 5, -1],
164        [0, -1, 0]
165    ], dtype=np.float32)
166    sharpened = cv2.filter2D(original, -1, kernel_sharpen)
167
168    # ๊ฐ•ํ•œ ์ƒคํ”„๋‹
169    kernel_sharpen_strong = np.array([
170        [-1, -1, -1],
171        [-1, 9, -1],
172        [-1, -1, -1]
173    ], dtype=np.float32)
174    sharpened_strong = cv2.filter2D(original, -1, kernel_sharpen_strong)
175
176    # ์— ๋ณด์‹ฑ ์ปค๋„
177    kernel_emboss = np.array([
178        [-2, -1, 0],
179        [-1, 1, 1],
180        [0, 1, 2]
181    ], dtype=np.float32)
182    embossed = cv2.filter2D(original, -1, kernel_emboss)
183
184    print("์ปค์Šคํ…€ ์ปค๋„ ์˜ˆ์‹œ:")
185    print(f"  ํ‰๊ท  ํ•„ํ„ฐ:\n{kernel_avg}")
186    print(f"\n  ์ƒคํ”„๋‹:\n{kernel_sharpen}")
187    print(f"\n  ์— ๋ณด์‹ฑ:\n{kernel_emboss}")
188
189    cv2.imwrite('custom_avg.jpg', avg_filtered)
190    cv2.imwrite('custom_sharpen.jpg', sharpened)
191    cv2.imwrite('custom_sharpen_strong.jpg', sharpened_strong)
192    cv2.imwrite('custom_emboss.jpg', embossed)
193
194
195def unsharp_masking_demo():
196    """์–ธ์ƒคํ”„ ๋งˆ์Šคํ‚น ๋ฐ๋ชจ"""
197    print("\n" + "=" * 50)
198    print("์–ธ์ƒคํ”„ ๋งˆ์Šคํ‚น (Unsharp Masking)")
199    print("=" * 50)
200
201    original, _ = create_noisy_image()
202
203    # ์–ธ์ƒคํ”„ ๋งˆ์Šคํ‚น: ์›๋ณธ + (์›๋ณธ - ๋ธ”๋Ÿฌ) * ๊ฐ•๋„
204    blurred = cv2.GaussianBlur(original, (5, 5), 0)
205
206    # ๋ฐฉ๋ฒ• 1: ์ง์ ‘ ๊ณ„์‚ฐ
207    unsharp = cv2.addWeighted(original, 1.5, blurred, -0.5, 0)
208
209    # ๋ฐฉ๋ฒ• 2: ๊ณต์‹ ์ ์šฉ
210    alpha = 1.5  # ์ƒคํ”„๋‹ ๊ฐ•๋„
211    unsharp2 = cv2.addWeighted(original, 1 + alpha, blurred, -alpha, 0)
212
213    print("์–ธ์ƒคํ”„ ๋งˆ์Šคํ‚น:")
214    print("  ๊ฒฐ๊ณผ = ์›๋ณธ + alpha * (์›๋ณธ - ๋ธ”๋Ÿฌ)")
215    print("  alpha๊ฐ€ ํด์ˆ˜๋ก ์ƒคํ”„๋‹ ํšจ๊ณผ ๊ฐ•ํ•จ")
216
217    cv2.imwrite('unsharp_mask.jpg', unsharp)
218    cv2.imwrite('unsharp_mask2.jpg', unsharp2)
219
220
221def filter_comparison():
222    """ํ•„ํ„ฐ ๋น„๊ต"""
223    print("\n" + "=" * 50)
224    print("ํ•„ํ„ฐ ๋น„๊ต ์ •๋ฆฌ")
225    print("=" * 50)
226
227    print("""
228    | ํ•„ํ„ฐ | ํŠน์ง• | ์‚ฌ์šฉ ์ƒํ™ฉ |
229    |------|------|----------|
230    | blur (Box) | ๊ท ์ผํ•œ ๊ฐ€์ค‘์น˜ | ๋‹จ์ˆœ ํ‰๊ท ํ™” |
231    | GaussianBlur | ์ค‘์•™ ๊ฐ€์ค‘์น˜ ๋†’์Œ | ์ž์—ฐ์Šค๋Ÿฌ์šด ๋ธ”๋Ÿฌ |
232    | medianBlur | ์ค‘์•™๊ฐ’ ์‚ฌ์šฉ | ์†Œ๊ธˆ-ํ›„์ถ” ๋…ธ์ด์ฆˆ |
233    | bilateralFilter | ์—ฃ์ง€ ๋ณด์กด | ํ”ผ๋ถ€ ๋ณด์ • ๋“ฑ |
234    """)
235
236
237def main():
238    """๋ฉ”์ธ ํ•จ์ˆ˜"""
239    # ๋ธ”๋Ÿฌ ํ•„ํ„ฐ
240    blur_demo()
241
242    # ๊ฐ€์šฐ์‹œ์•ˆ ๋ธ”๋Ÿฌ
243    gaussian_blur_demo()
244
245    # ๋ฏธ๋””์–ธ ๋ธ”๋Ÿฌ
246    median_blur_demo()
247
248    # ์–‘๋ฐฉํ–ฅ ํ•„ํ„ฐ
249    bilateral_filter_demo()
250
251    # ์ปค์Šคํ…€ ํ•„ํ„ฐ
252    custom_filter_demo()
253
254    # ์–ธ์ƒคํ”„ ๋งˆ์Šคํ‚น
255    unsharp_masking_demo()
256
257    # ๋น„๊ต
258    filter_comparison()
259
260    print("\n์ด๋ฏธ์ง€ ํ•„ํ„ฐ๋ง ๋ฐ๋ชจ ์™„๋ฃŒ!")
261
262
263if __name__ == '__main__':
264    main()