<jupyter_start><jupyter_text>今回のROI(白用紙の部分)について画像全体のサイズ…600x800Region of Interesting(矩形の左上と右下の点座標)1701~1781まで…(270, 240), (580, 670)あたり1782~1794まで…(250, 240), (560, 670)あたりRoIサイズ…310x430<jupyter_code>img_01_to_81 = load_img(images_path[0])
RoI_01_to_81 = img_01_to_81[270:580, 240:670, :]
img_rest = load_img(images_path[80])
RoI_rest = img_rest[250:560, 240:670, :]

plt.figure(figsize=(12, 6))
plt.subplot(221); plt.imshow(img_01_to_81)
plt.subplot(222); plt.imshow(RoI_01_to_81)
plt.subplot(223); plt.imshow(img_rest)
plt.subplot(224); plt.imshow(RoI_rest)
plt.show()<jupyter_output><empty_output><jupyter_text>RoI部分の保存<jupyter_code># 保存先ディレクトリがなければ作成
save_dir = './datasets/train/images/'
if not os.path.exists(save_dir):
    os.mkdir(save_dir)
for i, path in enumerate(images_path):
    img = load_img(path)
    if i < 80:
        RoI = img[270:580, 240:670, :]          # RoI，トレー内の白紙の部分
    else:
        RoI = img[250:560, 240:670, :]
    RoI = cv2.cvtColor(RoI, cv2.COLOR_RGB2BGR)  # opencvの関数で保存するため，再変換
        
    file_name = path[-12:]                      # ファイル名(.pngの部分)
    save_path = os.path.join(save_dir, 'train_' + file_name)
    cv2.imwrite(save_path, RoI)<jupyter_output><empty_output><jupyter_text>手動でのマスク画像の作成<jupyter_code>img = load_img(images_path[0], gray=True)  # 57とかヤバい
RoI = img[270:580, 240:670]

RoI = cv2.medianBlur(RoI, 11)
ret, thresh = cv2.threshold(RoI, 102, 255, cv2.THRESH_BINARY)
ada_thresh = cv2.adaptiveThreshold(RoI, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 99, 0)

# 白黒反転
thresh = ~thresh
ada_thresh = ~ada_thresh

# クロージング(内部の黒点除去)してから収縮して結合を切る
kernel_closing = np.ones((5, 5), np.uint8)
kernel_erosion = np.ones((5, 5), np.uint8)
ada_thresh_closing = cv2.morphologyEx(ada_thresh, cv2.MORPH_CLOSE, kernel_closing)
ada_thresh_erosion = cv2.erode(ada_thresh_closing, kernel_erosion, iterations=1)

plt.figure(figsize=(12, 8))
plt.subplot(221); plt.imshow(RoI, cmap='gray')
plt.subplot(222); plt.imshow(thresh, cmap='gray')
plt.subplot(223); plt.imshow(ada_thresh, cmap='gray')
plt.subplot(224); plt.imshow(ada_thresh_erosion, cmap='gray')
plt.show()<jupyter_output><empty_output><jupyter_text>Watershedを試してみる<jupyter_code>images_path[2]
img = load_img(images_path[2], gray=False)
RoI = img[270:580, 240:670]
RoI_gray = cv2.cvtColor(RoI, cv2.COLOR_BGR2GRAY)

# 大津の閾値処理
thresh, bin_img = cv2.threshold(RoI_gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
print('大津法の二値化によって自動で決定された閾値:', thresh)

# ノイズ除去(opening: 収縮後に膨張)
kernel = np.ones((3, 3), np.uint8)
opening = cv2.morphologyEx(bin_img, cv2.MORPH_OPEN, kernel, iterations=2)

plt.figure(figsize=(12, 4))
plt.subplot(121); plt.imshow(bin_img, cmap='gray'); plt.title('Otsu')
plt.subplot(122); plt.imshow(opening, cmap='gray'); plt.title('Opening: noise reduction')
plt.show()
# 距離変換を行う(オブジェクトと背景の距離を出す)
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
plt.imshow(dist_transform)
plt.title('distance')
plt.show()
# 膨張させて，明確な背景(sure background)情報を得る
sure_bg = cv2.dilate(opening, kernel, iterations=2)

# 明確な前景(sure foreground)を出す
ret, sure_fg = cv2.threshold(dist_transform, 0.5 * dist_transform.max(), 255, 0)
print('閾値(距離変換で得られた値の最大値×0.5):', ret)

# 背景でも前景でもないunknownな境界部分を抽出
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg, sure_fg)

plt.figure(figsize=(12, 4))
plt.subplot(131); plt.imshow(sure_bg, cmap='gray'); plt.title('sure background')
plt.subplot(132); plt.imshow(sure_fg, cmap='gray'); plt.title('sure foreground')
plt.subplot(133); plt.imshow(unknown, cmap='gray'); plt.title('unknown')
plt.show()
plt.figure(figsize=(12, 4))

# foregroundの1オブジェクトごとにラベリング
ret, markers = cv2.connectedComponents(sure_fg)
plt.subplot(131); plt.imshow(markers); plt.title('label')

# markersのデータの中身，0:背景 1以降:物体
print('before watershed : \n', np.unique(markers, return_counts=True))

# 0をunknown境界として用いるため，1を足して，1:背景 2以降:物体とする
markers += 1
markers[unknown == 255] = 0
plt.subplot(132); plt.imshow(markers); plt.title('add unknown')

# 0:unknown 1:背景 2以降:物体
print('add unknown : \n', np.unique(markers, return_counts=True))

# 各情報からwatershedを実行
markers = cv2.watershed(RoI, markers)
plt.subplot(133); plt.imshow(markers); plt.title('watershed')

# watershed実行後は-1:境界 1:背景 2以降:物体
print('after watershed : \n', np.unique(markers, return_counts=True))
# 境界の領域を青で塗る
RoI[markers == -1] = [0, 0, 255]
plt.imshow(RoI)
# マスク画像を生成
height, width, _ = RoI.shape
mask = np.zeros((height, width))  # 原型を作成

for i in range(2, 14):            # 1は背景のため除外
    mask[markers == i] = 255      # 領域部分を白に
mask[markers == i] = 255          # -1も境界のため白に

plt.imshow(mask, cmap='gray')<jupyter_output><empty_output><jupyter_text>マスク画像の保存<jupyter_code>save_dir = './datasets/train/masks/'
RoI_dir = './datasets/train/images/'
RoI_images_path = glob.glob(os.path.join(RoI_dir, '*.png'))
for path in RoI_images_path:
    img = load_img(path)
    mask = make_mask(img)
    
    file_name = path[-12:]  # ファイル名(.pngの部分)
    save_path = os.path.join(save_dir, 'train_' + file_name)
    cv2.imwrite(save_path, mask)<jupyter_output><empty_output>
StarcoderdataJupyterStructuredCleanDedup