1"""
212. ํ์คํ ๊ทธ๋จ ๋ถ์
3- calcHist (ํ์คํ ๊ทธ๋จ ๊ณ์ฐ)
4- equalizeHist (ํ์คํ ๊ทธ๋จ ํํํ)
5- CLAHE (์ ์ํ ํ์คํ ๊ทธ๋จ ํํํ)
6- ํ์คํ ๊ทธ๋จ ์ญํฌ์
7"""
8
9import cv2
10import numpy as np
11
12
13def create_low_contrast_image():
14 """์ ๋๋น ์ด๋ฏธ์ง ์์ฑ"""
15 img = np.zeros((300, 400), dtype=np.uint8)
16
17 # ์ข์ ๋ฒ์์ ๋ฐ๊ธฐ๊ฐ๋ง ์ฌ์ฉ (100-150)
18 img[:] = 120
19
20 # ๋ํ ๊ทธ๋ฆฌ๊ธฐ
21 cv2.rectangle(img, (50, 50), (150, 150), 140, -1)
22 cv2.circle(img, (300, 150), 60, 130, -1)
23 cv2.putText(img, 'LOW', (150, 250), cv2.FONT_HERSHEY_SIMPLEX, 1.5, 150, 2)
24
25 return img
26
27
28def create_color_image():
29 """์ปฌ๋ฌ ํ
์คํธ ์ด๋ฏธ์ง"""
30 img = np.zeros((300, 400, 3), dtype=np.uint8)
31
32 # ๋ค์ํ ์์ ์์ญ
33 img[0:150, 0:200] = [200, 50, 50] # ํ๋
34 img[0:150, 200:400] = [50, 200, 50] # ์ด๋ก
35 img[150:300, 0:200] = [50, 50, 200] # ๋นจ๊ฐ
36 img[150:300, 200:400] = [200, 200, 50] # ์ฒญ๋ก
37
38 return img
39
40
41def calc_histogram_demo():
42 """ํ์คํ ๊ทธ๋จ ๊ณ์ฐ ๋ฐ๋ชจ"""
43 print("=" * 50)
44 print("ํ์คํ ๊ทธ๋จ ๊ณ์ฐ (calcHist)")
45 print("=" * 50)
46
47 img = create_low_contrast_image()
48
49 # ํ์คํ ๊ทธ๋จ ๊ณ์ฐ
50 # images: ์
๋ ฅ ์ด๋ฏธ์ง ๋ฆฌ์คํธ
51 # channels: ์ฑ๋ ์ธ๋ฑ์ค (๊ทธ๋ ์ด: [0], BGR: [0], [1], [2])
52 # mask: ๋ง์คํฌ (None = ์ ์ฒด)
53 # histSize: ๋น ๊ฐ์ (๋ณดํต 256)
54 # ranges: ๊ฐ ๋ฒ์
55
56 hist = cv2.calcHist([img], [0], None, [256], [0, 256])
57
58 print(f"ํ์คํ ๊ทธ๋จ shape: {hist.shape}")
59 print(f"์ด ํฝ์
์: {hist.sum()}")
60 print(f"์ต๋ ๋น๋ ๊ฐ: {hist.max():.0f}")
61 print(f"์ต๋ ๋น๋ ์์น: {hist.argmax()}")
62
63 # ํ์คํ ๊ทธ๋จ ์๊ฐํ (ํ
์คํธ)
64 print("\nํ์คํ ๊ทธ๋จ ๋ถํฌ (๊ฐ๋ต):")
65 for i in range(0, 256, 32):
66 count = hist[i:i+32].sum()
67 bar = '#' * int(count / 1000)
68 print(f" {i:3d}-{i+31:3d}: {bar} ({count:.0f})")
69
70 cv2.imwrite('histogram_input.jpg', img)
71
72 return hist
73
74
75def histogram_color_demo():
76 """์ปฌ๋ฌ ํ์คํ ๊ทธ๋จ ๋ฐ๋ชจ"""
77 print("\n" + "=" * 50)
78 print("์ปฌ๋ฌ ํ์คํ ๊ทธ๋จ")
79 print("=" * 50)
80
81 img = create_color_image()
82
83 # BGR ๊ฐ ์ฑ๋ ํ์คํ ๊ทธ๋จ
84 colors = ('b', 'g', 'r')
85
86 for i, color in enumerate(colors):
87 hist = cv2.calcHist([img], [i], None, [256], [0, 256])
88 peak = hist.argmax()
89 print(f"{color.upper()} ์ฑ๋: ์ต๋ ๋น๋ ์์น={peak}, ๊ฐ={hist[peak][0]:.0f}")
90
91 cv2.imwrite('histogram_color.jpg', img)
92
93
94def equalize_histogram_demo():
95 """ํ์คํ ๊ทธ๋จ ํํํ ๋ฐ๋ชจ"""
96 print("\n" + "=" * 50)
97 print("ํ์คํ ๊ทธ๋จ ํํํ (equalizeHist)")
98 print("=" * 50)
99
100 img = create_low_contrast_image()
101
102 # ํ์คํ ๊ทธ๋จ ํํํ
103 equalized = cv2.equalizeHist(img)
104
105 # ์ ํ ํต๊ณ ๋น๊ต
106 print("ํํํ ์ :")
107 print(f" Min={img.min()}, Max={img.max()}")
108 print(f" Mean={img.mean():.1f}, Std={img.std():.1f}")
109
110 print("\nํํํ ํ:")
111 print(f" Min={equalized.min()}, Max={equalized.max()}")
112 print(f" Mean={equalized.mean():.1f}, Std={equalized.std():.1f}")
113
114 print("\nํํํ ํจ๊ณผ:")
115 print(" - ๋ช
์ ๋๋น ํฅ์")
116 print(" - ํ์คํ ๊ทธ๋จ์ด ๊ท ์ผํ๊ฒ ๋ถํฌ")
117 print(" - ์ ์ฒด ์ด๋ฏธ์ง์ ๋์ผํ๊ฒ ์ ์ฉ")
118
119 cv2.imwrite('equalize_before.jpg', img)
120 cv2.imwrite('equalize_after.jpg', equalized)
121
122
123def clahe_demo():
124 """CLAHE ๋ฐ๋ชจ"""
125 print("\n" + "=" * 50)
126 print("CLAHE (Contrast Limited Adaptive Histogram Equalization)")
127 print("=" * 50)
128
129 img = create_low_contrast_image()
130
131 # ์ผ๋ฐ ํํํ
132 equalized = cv2.equalizeHist(img)
133
134 # CLAHE
135 # clipLimit: ๋๋น ์ ํ (๋์์๋ก ๋๋น ๊ฐํจ)
136 # tileGridSize: ํ์ผ ํฌ๊ธฐ
137
138 clahe1 = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
139 clahe2 = cv2.createCLAHE(clipLimit=4.0, tileGridSize=(8, 8))
140 clahe3 = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(16, 16))
141
142 result1 = clahe1.apply(img)
143 result2 = clahe2.apply(img)
144 result3 = clahe3.apply(img)
145
146 print("CLAHE vs ์ผ๋ฐ ํํํ:")
147 print(" - CLAHE: ์ง์ญ์ ์ผ๋ก ์ ์ฉ (ํ์ผ ๋จ์)")
148 print(" - ๋
ธ์ด์ฆ ์ฆํญ ๋ฐฉ์ง (clipLimit)")
149 print(" - ๋ถ๊ท ์ผ ์กฐ๋ช
์ ํจ๊ณผ์ ")
150
151 print("\nCLAHE ํ๋ผ๋ฏธํฐ:")
152 print(" clipLimit: ๋๋น ์ ํ (2.0~4.0 ๊ถ์ฅ)")
153 print(" tileGridSize: ํ์ผ ํฌ๊ธฐ (8x8 ๊ถ์ฅ)")
154
155 cv2.imwrite('clahe_equalized.jpg', equalized)
156 cv2.imwrite('clahe_2_8.jpg', result1)
157 cv2.imwrite('clahe_4_8.jpg', result2)
158 cv2.imwrite('clahe_2_16.jpg', result3)
159
160
161def clahe_color_demo():
162 """์ปฌ๋ฌ ์ด๋ฏธ์ง CLAHE ๋ฐ๋ชจ"""
163 print("\n" + "=" * 50)
164 print("์ปฌ๋ฌ ์ด๋ฏธ์ง CLAHE")
165 print("=" * 50)
166
167 img = create_color_image()
168
169 # LAB ์์ ๊ณต๊ฐ์ผ๋ก ๋ณํ
170 lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
171 l, a, b = cv2.split(lab)
172
173 # L ์ฑ๋์๋ง CLAHE ์ ์ฉ
174 clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
175 l_clahe = clahe.apply(l)
176
177 # ๋ค์ ๋ณํฉ
178 lab_clahe = cv2.merge([l_clahe, a, b])
179 result = cv2.cvtColor(lab_clahe, cv2.COLOR_LAB2BGR)
180
181 print("์ปฌ๋ฌ ์ด๋ฏธ์ง CLAHE ๋ฐฉ๋ฒ:")
182 print(" 1. BGR โ LAB ๋ณํ")
183 print(" 2. L ์ฑ๋์ CLAHE ์ ์ฉ")
184 print(" 3. LAB โ BGR ๋ณํ")
185 print(" (์์(a,b)์ ์ ์ง, ๋ฐ๊ธฐ(L)๋ง ์กฐ์ )")
186
187 cv2.imwrite('clahe_color_before.jpg', img)
188 cv2.imwrite('clahe_color_after.jpg', result)
189
190
191def histogram_comparison_demo():
192 """ํ์คํ ๊ทธ๋จ ๋น๊ต ๋ฐ๋ชจ"""
193 print("\n" + "=" * 50)
194 print("ํ์คํ ๊ทธ๋จ ๋น๊ต (compareHist)")
195 print("=" * 50)
196
197 # ๋น๊ตํ ์ด๋ฏธ์ง๋ค ์์ฑ
198 img1 = np.zeros((100, 100), dtype=np.uint8)
199 img1[:] = 100
200 cv2.rectangle(img1, (20, 20), (80, 80), 150, -1)
201
202 img2 = img1.copy() # ๋์ผ
203
204 img3 = np.zeros((100, 100), dtype=np.uint8)
205 img3[:] = 50
206 cv2.rectangle(img3, (20, 20), (80, 80), 200, -1)
207
208 # ํ์คํ ๊ทธ๋จ ๊ณ์ฐ
209 hist1 = cv2.calcHist([img1], [0], None, [256], [0, 256])
210 hist2 = cv2.calcHist([img2], [0], None, [256], [0, 256])
211 hist3 = cv2.calcHist([img3], [0], None, [256], [0, 256])
212
213 # ์ ๊ทํ
214 cv2.normalize(hist1, hist1, 0, 1, cv2.NORM_MINMAX)
215 cv2.normalize(hist2, hist2, 0, 1, cv2.NORM_MINMAX)
216 cv2.normalize(hist3, hist3, 0, 1, cv2.NORM_MINMAX)
217
218 # ๋น๊ต ๋ฐฉ๋ฒ
219 methods = [
220 (cv2.HISTCMP_CORREL, 'Correlation'),
221 (cv2.HISTCMP_CHISQR, 'Chi-Square'),
222 (cv2.HISTCMP_INTERSECT, 'Intersection'),
223 (cv2.HISTCMP_BHATTACHARYYA, 'Bhattacharyya'),
224 ]
225
226 print("img1 vs img2 (๋์ผ), img1 vs img3 (๋ค๋ฆ):\n")
227
228 for method, name in methods:
229 score12 = cv2.compareHist(hist1, hist2, method)
230 score13 = cv2.compareHist(hist1, hist3, method)
231 print(f" {name:15}: ๋์ผ={score12:.4f}, ๋ค๋ฆ={score13:.4f}")
232
233 print("\n๋น๊ต ๋ฐฉ๋ฒ ํด์:")
234 print(" Correlation: 1์ ๊ฐ๊น์ธ์๋ก ์ ์ฌ")
235 print(" Chi-Square: 0์ ๊ฐ๊น์ธ์๋ก ์ ์ฌ")
236 print(" Intersection: ํด์๋ก ์ ์ฌ")
237 print(" Bhattacharyya: 0์ ๊ฐ๊น์ธ์๋ก ์ ์ฌ")
238
239
240def back_projection_demo():
241 """ํ์คํ ๊ทธ๋จ ์ญํฌ์ ๋ฐ๋ชจ"""
242 print("\n" + "=" * 50)
243 print("ํ์คํ ๊ทธ๋จ ์ญํฌ์ (Back Projection)")
244 print("=" * 50)
245
246 # ๋์ ์ด๋ฏธ์ง (๋ค์ํ ์์)
247 target = np.zeros((300, 400, 3), dtype=np.uint8)
248 target[:] = [100, 100, 100] # ํ์ ๋ฐฐ๊ฒฝ
249
250 # ๋นจ๊ฐ ๋ฌผ์ฒด๋ค
251 cv2.circle(target, (100, 100), 40, (50, 50, 200), -1)
252 cv2.circle(target, (300, 200), 50, (30, 30, 180), -1)
253 cv2.rectangle(target, (150, 200), (220, 280), (40, 40, 210), -1)
254
255 # ํ๋ ๋ฌผ์ฒด
256 cv2.circle(target, (350, 100), 30, (200, 50, 50), -1)
257
258 # ROI (๋นจ๊ฐ์ ์ํ)
259 roi = target[60:140, 60:140] # ๋นจ๊ฐ ์ ์์ญ
260
261 # HSV ๋ณํ
262 hsv_target = cv2.cvtColor(target, cv2.COLOR_BGR2HSV)
263 hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
264
265 # ROI ํ์คํ ๊ทธ๋จ ๊ณ์ฐ (Hue, Saturation๋ง)
266 roi_hist = cv2.calcHist([hsv_roi], [0, 1], None, [180, 256], [0, 180, 0, 256])
267 cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX)
268
269 # ์ญํฌ์
270 back_proj = cv2.calcBackProject([hsv_target], [0, 1], roi_hist, [0, 180, 0, 256], 1)
271
272 # ๊ฒฐ๊ณผ ๊ฐ์ (ํํํ์ ์ฐ์ฐ)
273 kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
274 cv2.filter2D(back_proj, -1, kernel, back_proj)
275 _, thresh = cv2.threshold(back_proj, 50, 255, cv2.THRESH_BINARY)
276
277 print("์ญํฌ์ ๊ณผ์ :")
278 print(" 1. ROI์ ํ์คํ ๊ทธ๋จ ๊ณ์ฐ")
279 print(" 2. ๋์ ์ด๋ฏธ์ง์ ๊ฐ ํฝ์
์ด ROI์ ์ผ๋ง๋ ์ ์ฌํ์ง ๊ณ์ฐ")
280 print(" 3. ์ ์ฌํ ์์ ์์ญ์ด ๋ฐ๊ฒ ํ์๋จ")
281 print(" 4. ๊ฐ์ฒด ์ถ์ ์ ํ์ฉ (MeanShift, CamShift)")
282
283 cv2.imwrite('backproj_target.jpg', target)
284 cv2.imwrite('backproj_roi.jpg', roi)
285 cv2.imwrite('backproj_result.jpg', back_proj)
286 cv2.imwrite('backproj_thresh.jpg', thresh)
287
288
289def main():
290 """๋ฉ์ธ ํจ์"""
291 # ํ์คํ ๊ทธ๋จ ๊ณ์ฐ
292 calc_histogram_demo()
293
294 # ์ปฌ๋ฌ ํ์คํ ๊ทธ๋จ
295 histogram_color_demo()
296
297 # ํ์คํ ๊ทธ๋จ ํํํ
298 equalize_histogram_demo()
299
300 # CLAHE
301 clahe_demo()
302
303 # ์ปฌ๋ฌ CLAHE
304 clahe_color_demo()
305
306 # ํ์คํ ๊ทธ๋จ ๋น๊ต
307 histogram_comparison_demo()
308
309 # ์ญํฌ์
310 back_projection_demo()
311
312 print("\nํ์คํ ๊ทธ๋จ ๋ถ์ ๋ฐ๋ชจ ์๋ฃ!")
313
314
315if __name__ == '__main__':
316 main()