Pythonでの画像の細線化

実現したいこと

・任意の画像を読み込み、細線化する

前提

Python3.9、OpenCV2、numpyを用いて画像処理を行っています。
後述の通りにコードを書いたのですが、出力される画像が細線化されたものではなく、以下に示す画像のようになってしまいました。

発生している問題・エラーメッセージ

得られた画像("error_Lena.jpg")
イメージ説明

エラーメッセージは発生していません。

該当のソースコード

import cv2 import numpy as np class Thinning: def __init__(self): pass def thinning(self, bin_img, iterative_limit=-1): if iterative_limit == -1: iterative_limit = 60000 thinned_image = bin_img.copy() kernel1 = np.array([[0, 1, 1], [0, 1, 0], [1, 1, 0]], dtype=np.uint8) kernel2 = np.array([[1, 1, 0], [1, 1, 0], [0, 1, 0]], dtype=np.uint8) for it in range(iterative_limit): prev_image = thinned_image.copy() for i in range(1, bin_img.shape[0] - 1): for j in range(1, bin_img.shape[1] - 1): if not bin_img[i, j]: continue neighbor1 = bin_img[i - 1:i + 2, j - 1:j + 2] neighbor2 = bin_img[i - 1:i + 2, j - 1:j + 2] b1 = (not neighbor1[1, 2]) and (neighbor1[0, 1] or neighbor1[2, 1]) b2 = (not neighbor1[1, 0]) and (neighbor1[0, 1] or neighbor1[2, 1]) b3 = (not neighbor2[0, 1]) and (neighbor2[1, 0] or neighbor2[1, 2]) b4 = (not neighbor2[2, 1]) and (neighbor2[1, 0] or neighbor2[1, 2]) g1 = (b1 + b2 + b3 + b4) == 1 np1 = np.sum(neighbor1) np2 = np.sum(neighbor2) npm = np.minimum(np1, np2) g2 = (npm >= 2) and (npm <= 3) g3 = not (bin_img[i, j + 1] and (bin_img[i - 1, j + 1] or bin_img[i + 1, j + 1] or (not bin_img[i + 1, j - 1]))) g4 = not (bin_img[i, j - 1] and (bin_img[i - 1, j - 1] or bin_img[i + 1, j - 1] or (not bin_img[i - 1, j + 1]))) if g1 and g2 and g3: thinned_image[i, j] = 0 elif g1 and g2 and g4: thinned_image[i, j] = 0 if np.all(prev_image == thinned_image): break # Clear edge bar thinned_image[:16, :] = 0 thinned_image[-16:, :] = 0 thinned_image[:, :16] = 0 thinned_image[:, -16:] = 0 return thinned_image def thinning_control(self, src, iterative_limit=-1): bin_img = (src & 1).astype(np.uint8) thinned_image = self.thinning(bin_img, iterative_limit) return thinned_image * 255 if __name__ == '__main__': # 画像を読み込む input_image = cv2.imread('Lena.ppm', cv2.IMREAD_GRAYSCALE) # インスタンスを作成 thinning = Thinning() # 細線化処理を実行 thinned_image = thinning.thinning_control(input_image) # 細線化した画像を表示 cv2.imwrite('error_Lena.jpg', thinned_image) cv2.imshow('Thinned Image', thinned_image) cv2.waitKey(0) cv2.destroyAllWindows()

試したこと

画像を変えてみたところ、次のようになりました。イメージ説明

イメージ説明

補足情報(FW/ツールのバージョンなど)

使用した"Lena.ppm"は以下の画像です。
イメージ説明

環境は以下の通りです。
Mac OS 13.3.1(a) Ventura
VSCode 1.62.3

コメントを投稿

0 コメント