import cv2
import numpy as np
# 元画像とテンプレート画像のパス
image_path = "checkerboard.png"
# 元画像を読み込む
img = cv2.imread(image_path)
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# テンプレート画像として使用する部分を指定して切り取る(例: 画像の左上を30%の範囲で切り取る)
height, width = gray_img.shape
cut_width = int(width * 0.30)
cut_height = int(height * 0.30)
template = gray_img[0:cut_height, 0:cut_width]
# テンプレートマッチングを実行
result = cv2.matchTemplate(gray_img, template, cv2.TM_CCOEFF_NORMED)
# マッチングのしきい値を0.99に設定
threshold = 0.99
loc = np.where(result >= threshold)
# 初期化
min_y_when_x_zero = float('inf')
min_x_when_y_zero = float('inf')
# 見つかった場所をチェック
for pt in zip(*loc[::-1]):
if pt[0] == 0 and pt != (0, 0):
min_y_when_x_zero = min(min_y_when_x_zero, pt[1])
if pt[1] == 0 and pt != (0, 0):
min_x_when_y_zero = min(min_x_when_y_zero, pt[0])
# 結果をプリント
print(f"Xがゼロのときの最小Yの座標 (excluding (0, 0)): {min_y_when_x_zero}")
print(f"Yがゼロのときの最小Xの座標 (excluding (0, 0)): {min_x_when_y_zero}")
# 指定された範囲を元画像から切り取る
if min_x_when_y_zero != float('inf') and min_y_when_x_zero != float('inf'):
cropped_img = img[0:min_y_when_x_zero - 1, 0:min_x_when_y_zero - 1]
# 切り取った画像を保存
output_cropped_path = "output_cropped.png"
cv2.imwrite(output_cropped_path, cropped_img)
print(f"切り取った画像を保存しました: {output_cropped_path}")
# 見つかった場所を赤い矩形で囲む
for pt in zip(*loc[::-1]):
if pt != (0, 0):
cv2.rectangle(img, pt, (pt[0] + cut_width, pt[1] + cut_height), (0, 0, 255), 2)
# 結果を保存
output_path = "output_detected.png"
cv2.imwrite(output_path, img)
print(f"結果を保存しました: {output_path}")
import cv2
import numpy as np
import os
from glob import glob
from cvplus import cvt
def process_image(img, cut_percentage=0.30, matching_threshold=0.95, inf=True):
copied_image = img.copy()
if len(img.shape) == 3 and img.shape[2] == 4:
# アルファチャネルがある場合
# アルファチャンネルを取得
alpha_channel = img[:, :, 3]
# アルファチャンネルがすべて255か確認
if np.all(alpha_channel == 255):
# アルファチャンネルを取り除く
bgr_img = img[:, :, :3]
_, white_img = cv2.threshold(bgr_img, 128, 255, cv2.THRESH_BINARY)
else:
b, g, r, a = cv2.split(img)
white_img = cv2.merge((b, g, r, a))
white_img[a <= 10] = [255, 255, 255, 255] # 背景が透明な部分を白に変更
white_img[a > 10] = [0, 0, 0, 255] # 透明でない部分を黒に変更
else: # アルファチャネルがない場合
_, white_img = cv2.threshold(img, 128, 255, cv2.THRESH_BINARY)
gray_img = cv2.cvtColor(cv2.cvtColor(white_img, cv2.COLOR_BGRA2BGR), cv2.COLOR_BGR2GRAY)
if np.all(gray_img == 0) or np.all(gray_img == 255):
return None, gray_img, copied_image
height, width = gray_img.shape
cut_width = int(width * cut_percentage)
cut_height = int(height * cut_percentage)
template = gray_img[0:cut_height, 0:cut_width]
result = cv2.matchTemplate(gray_img, template, cv2.TM_CCOEFF_NORMED)
loc = np.where(result >= matching_threshold)
for pt in zip(*loc[::-1]):
if pt != (0, 0):
cv2.rectangle(copied_image, pt, (pt[0] + cut_width, pt[1] + cut_height), (0, 0, 255), 2)
min_y_when_x_zero = float('inf')
min_x_when_y_zero = float('inf')
for pt in zip(*loc[::-1]):
if pt[0] == 0 and pt != (0, 0) and pt[1] != 1:
min_y_when_x_zero = min(min_y_when_x_zero, pt[1])
if pt[1] == 0 and pt != (0, 0) and pt[0] != 1:
min_x_when_y_zero = min(min_x_when_y_zero, pt[0])
print(f"Xがゼロのときの最小Yの座標: {min_y_when_x_zero}")
print(f"Yがゼロのときの最小Xの座標: {min_x_when_y_zero}")
if min_y_when_x_zero == 2:
min_y_when_x_zero = min_x_when_y_zero
if inf==False:
if min_x_when_y_zero == float('inf'):
min_x_when_y_zero = width
if min_y_when_x_zero == float('inf'):
min_y_when_x_zero = height
if min_x_when_y_zero != float('inf') and min_y_when_x_zero != float('inf'):
cropped_img = white_img[0:min_y_when_x_zero - 1, 0:min_x_when_y_zero - 1]
else:
cropped_img = None
return cropped_img, gray_img, copied_image
def process_images(input_folder, output_folder):
os.makedirs(output_folder, exist_ok=True)
image_files = glob(os.path.join(input_folder, "*.png")) + glob(os.path.join(input_folder, "*.jpg")) + glob(os.path.join(input_folder, "*.jpeg"))
for image_path in image_files:
img = cvt.imread(image_path, cv2.IMREAD_UNCHANGED)
thresholds = [0.99, 0.97, 0.95]
cut_percentages = [1/3, 1/4, 1/5, 1/10, 1/20]
for cut_percentage in cut_percentages:
for threshold in thresholds:
cropped_img, gray_img, copied_image = process_image(img, cut_percentage=cut_percentage, matching_threshold=threshold, inf=True)
if cropped_img is not None:
break
if cropped_img is not None:
break
base_name = os.path.basename(image_path)
name, ext = os.path.splitext(base_name)
output_detected_path = os.path.join(output_folder, f"{name}_detected{ext}")
cvt.imwrite(output_detected_path, copied_image)
print(f"結果を保存しました: {output_detected_path}")
output_white_bg_path = os.path.join(output_folder, f"{name}_white_bg{ext}")
cvt.imwrite(output_white_bg_path, gray_img)
print(f"背景が白になった画像を保存しました: {output_white_bg_path}")
if cropped_img is not None:
output_cropped_path = os.path.join(output_folder, f"{name}_cropped{ext}")
cvt.imwrite(output_cropped_path, cropped_img)
print(f"切り取った画像を保存しました: {output_cropped_path}")
if __name__ == "__main__":
input_folder = r"d:\wagara"
output_folder = r"Y:\lin"
process_images(input_folder, output_folder)
ディスカッション
コメント一覧
まだ、コメントがありません