'22/05/01更新:CADで読み込めるsvgを作成する雛形コードを載せました。
画像ファイルjpgやpng等は、ドット(画素)絵でラスタ形式と呼びます。そして、画像ファイルsvg(Scalable Vector Graphics)をベクタ形式と呼び、曲線でも解像度に依らずに滑らかに表示できます。その仕組みは、xmlベースで線を式の計算によって表示するためです。画像ファイルをsvgファイルの書式フォーマットへ変換できれば、CADソフトで読み込むことが可能になります。
例えば、下図のように目玉焼きのような図があります。図中の白身の輪郭を手動でなぞって描くには困難です。
そこで、OpenCVを用いて下図のように画像認識の処理により境界を検出します。
同時に、下記のように境界座標を取得できます。
上記のような(x, y)座標データがあれば、svgwriteのpolygonメソッドにてsvgファイルを作成できます。下図は、そのsvg画像ファイルをメモ帳で開いた例です。数値が並んでいます。
そして、作成したsvgファイルは、CADソフトで読み込めるようになります。下図は「FreeCAD」で読み込んだ例です。
以上のようにすることで、複雑な2次元画像であっても、CADソフトで読み込み、下図のように押し出したりして3次元構造を作成できるようになります。
■「OpenCV」と「svgwrite」のインストール
ライブラリのインストールは次のようにします。
pip install opencv-python
pip install svgwrite
■本プログラム
import os
import cv2
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import svgwrite
file_path = './pictures/medama_yaki_color.jpg'
file_name = os.path.basename(file_path)
fname, ext = os.path.splitext(file_name)
print(fname, ext)
save_dir = './save_dir/'
img = cv2.imread(file_path)
plt.imshow(img)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
plt.imshow(gray)
contour = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 9, 5)
plt.imshow(contour)
contours, hierarchy = cv2.findContours(contour, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
print(len(contours))
print(hierarchy)
x_list = []
y_list = []
df_group_list = []
for i in range(len(contours)):
if hierarchy[0][i][-1] == -1:
buf_np = contours[i].flatten()
for i, elem in enumerate(buf_np):
if i%2 == 0:
x_list.append(elem)
else:
y_list.append(elem * (-1))
mylist = list(zip(x_list, y_list))
df_buf = pd.DataFrame(mylist, columns = ['x', 'y'])
df_group_list.append(df_buf)
x_list.clear()
y_list.clear()
print('df_group_list', len(df_group_list))
for i, df_buf in enumerate(df_group_list, start=1):
plt.scatter(df_buf['x'], df_buf['y'], s = 0.5)
plt.xlabel('x')
plt.ylabel('y')
plt.grid()
plt.show()
if True:
for i, df_buf in enumerate(df_group_list):
if not df_buf[(df_buf['x'] == 0) & (df_buf['y'] == 0)].empty:
df_group_list.pop(i)
DF_name_list = []
DF_list = []
for i, df_buf in enumerate(df_group_list, start=1):
plt.scatter(df_buf['x'], df_buf['y'], s = 0.5)
plt.xlabel('x')
plt.ylabel('y')
plt.grid()
DF_name_list.extend(['id_'+ '{0:03}'.format(i) + '_x', 'id_'+ '{0:03}'.format(i) + '_y'])
DF_list.append(df_buf)
DF = pd.concat(DF_list, axis=1)
DF.columns = DF_name_list
DF.to_excel(f'{save_dir}{fname}_04.xlsx', index=False)
plt.show()
outfile_name = f'{save_dir}{fname}_05_Draw.svg'
dwg = svgwrite.Drawing(outfile_name,
profile = 'tiny',
)
for num, df_buf in enumerate(df_group_list, start=1):
print(num, 'before', len(df_buf))
if True:
df_buf = df_buf[::10]
print(num, 'after', len(df_buf))
if len(df_buf) < 10:
continue
points = df_buf.to_numpy().tolist()
dwg.add(dwg.polygon(points = points,
stroke_width = 0,
fill = 'none',
id = 'id_' + '{0:03}'.format(num),
))
dwg.save()
del dwg
print('save', outfile_name)
下記コードも参考下さい。
hk29.hatenablog.jp
以上
<広告>
リンク
リンク