回答編集履歴

1

修正

2022/09/18 02:10

投稿

can110
can110

スコア38266

test CHANGED
@@ -1,23 +1,30 @@
1
- あらかじめ内部が塗りつぶされた画像、あるいは前処理でfindContoursで外接輪郭を塗りつぶした画像があれば、以下のように`morphologyEx`で輪郭をなめらかにすることができます。
1
+ あらかじめ内部が塗りつぶされた画像、あるいはfindContoursのような前処理で外接輪郭を塗りつぶした画像があれば、以下のように`morphologyEx`と`ModeFilter`で輪郭をなめらかにすることができます。
2
2
  ```Python
3
+ import numpy as np
3
4
  import cv2
5
+ from PIL import Image, ImageFilter
4
6
 
5
7
  # 中身が白、外側が黒に反転
6
8
  img = cv2.imread('pika.png')
7
9
  img2 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
8
- img2=255-img2
10
+ img2 = 255-img2
9
11
 
10
12
  # 円形(なめらか)に膨張
11
- kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (50,50)) # 膨張サイズは適当に
13
+ kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (40,40)) # 膨張サイズは適当に
12
- img3 = cv2.morphologyEx(img2, cv2.MORPH_DILATE, kernel)
14
+ img2 = cv2.morphologyEx(img2, cv2.MORPH_DILATE, kernel)
15
+
16
+ # モード(最頻)フィルターを適用
17
+ img2 = Image.fromarray(img2) # cv -> PIL
18
+ img2 = img2.filter(ImageFilter.ModeFilter(20))
19
+ img2 = np.array(img2, dtype=np.uint8) # PIL -> cv
13
20
 
14
21
  # 外接する輪郭を取得して内部を塗りつぶす
15
- contours, hierarchy = cv2.findContours(img3, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
22
+ contours, hierarchy = cv2.findContours(img2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
16
- img3 = cv2.drawContours(img, contours, -1, (0,0,0), thickness=cv2.FILLED)
23
+ img2 = cv2.drawContours(img, contours, -1, (0,0,0), thickness=cv2.FILLED)
17
- cv2.imwrite('ret.png', img3)
24
+ cv2.imwrite('ret.png', img2)
18
25
  ```
19
26
  pika.png
20
27
  ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-09-18/bcbff625-b3f7-4c53-ba28-d466c97fd3bf.png)
21
28
 
22
29
  ret.png
23
- ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-09-18/010910e0-b33c-4883-b8b2-695eeba23e1d.png)
30
+ ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-09-18/73bedcf2-a21b-47a1-ad2e-cb9213de7051.png)