diff --git a/3_10_bg_subtraction.py b/3_10_bg_subtraction.py new file mode 100644 index 0000000..11f3e95 --- /dev/null +++ b/3_10_bg_subtraction.py @@ -0,0 +1,97 @@ +# 実験課題10 +# 3.10 背景差分法(ラベリング・ノイズ処理含む) + +import cv2 +import numpy as np + +# Webカメラの初期化 +cap = cv2.VideoCapture(0) + +if not cap.isOpened(): + print("カメラを開けませんでした。") +else: + print("背景差分法を開始します。") + print("'q': 終了, 'r': 背景画像を現フレームで更新") + + # 最初のフレームを背景画像として取得するための準備 + bg_gray = None + + while True: + ret, frame = cap.read() + if not ret: + print("フレームを取得できませんでした。") + break + + # 差分計算を安定させるため、現フレームをグレースケール化 + gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + + # ガウシアンブラ(平滑化)を適用して、カメラ特有の細かいノイズを低減 + gray = cv2.GaussianBlur(gray, (21, 21), 0) + + # 起動直後、または 'r' キーが押された場合に背景画像を保存・更新する + if bg_gray is None: + bg_gray = gray + print("背景画像を保存しました。カメラの前から離れてください。") + continue + + # --- 3.101 背景差分法:背景画像と現フレームの絶対差分を計算 --- + frame_diff = cv2.absdiff(bg_gray, gray) + + # 差分画像を2値化して、動いている領域(前景)を白(255)にする + # 閾値は環境に合わせて調整(ここでは例として 25) + _, thresh = cv2.threshold(frame_diff, 25, 255, cv2.THRESH_BINARY) + + # --- 3.102 ノイズ処理(モルフォロジー演算:オープニング) --- + # 3.7で学んだ手法を使い、背景に散らばる小さなチラツキノイズを消去 + kernel = np.ones((5, 5), np.uint8) + thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel) + # 領域内の穴を埋めて結合を強める(クロージング) + thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel) + + # --- 3.102 ラベリング処理 --- + # 2値化画像から、繋がっている白い領域(動体)を検出してラベルを貼る + # nlabels: ラベルの総数(背景含む) + # labels: 各画素にラベル番号(0, 1, 2...)が割り当てられた画像 + # stats: 各領域の矩形座標や面積[x, y, w, h, area]の行列 + # centroids: 各領域の中心座標 + nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(thresh) + + # 各ラベルごとに色分けするためのランダムな色マップを作成(背景の0は黒にする) + # 乱数のシードを固定して、フレーム間で色が激しく変わるのを防ぐ + np.random.seed(42) + colors = np.random.randint(0, 255, (nlabels, 3), dtype=np.uint8) + colors[0] = [0, 0, 0] # ラベル0(背景)は黒に固定 + + # 画素ごとのラベル番号に対応する色を割り当てて、色分け画像(ラベリング画像)を作成 + labeled_img = colors[labels] + + # 動体領域に矩形(枠線)を描画する + for i in range(1, nlabels): # 0は背景なので1からループ + x = stats[i, cv2.CC_STAT_LEFT] + y = stats[i, cv2.CC_STAT_TOP] + w = stats[i, cv2.CC_STAT_WIDTH] + h = stats[i, cv2.CC_STAT_HEIGHT] + area = stats[i, cv2.CC_STAT_AREA] + + # 面積が小さすぎる領域(微小なノイズの残り)は無視する + if area > 500: + # 動体を緑色の矩形で囲む + cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) + # ラベル番号を画像上に描画 + cv2.putText(frame, f"ID:{i}", (x, y - 10), + cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) + + # --- 結果の表示 --- + cv2.imshow('Original Frame (Motion Detection)', frame) + cv2.imshow('Foreground Mask (Thresh)', thresh) + cv2.imshow('Labeled Components', labeled_img) + + # キー入力の受付 + key = cv2.waitKey(1) & 0xFF + if key == ord('q'): + break + elif key == ord('r'): + bg_gray = None # 次のループで背景が再キャプチャされる + + cap.release() + cv2.destroyAllWindows() \ No newline at end of file diff --git a/3_11_tracking.py b/3_11_tracking.py new file mode 100644 index 0000000..bbe32e0 --- /dev/null +++ b/3_11_tracking.py @@ -0,0 +1,87 @@ +# 実験課題11 +# 3.11 トラッキング(任意) + +import cv2 + +# Webカメラの初期化 +cap = cv2.VideoCapture(0) + +if not cap.isOpened(): + print("カメラを開けませんでした。") +else: + print("トラッキングテストを開始します。") + + # 最初の1フレームを読み込む + ret, frame = cap.read() + + if not ret: + print("フレームを取得できませんでした。") + else: + # --- 追跡対象の選択(ROI) --- + print("【操作方法】") + print("1. 追跡したい物体をマウスでドラッグして四角く囲んでください。") + print("2. 囲んだら Enter または Space キーを押して決定します。") + print("3. やり直す場合は 'c' キーを押してください。") + + # ユーザーに追跡対象をマウスで選択させるウィンドウを表示 + # bbox には選択された領域の (x, y, w, h) が格納される + while True: + # ユーザーに追跡対象をマウスで選択させる + bbox = cv2.selectROI("Tracking", frame, fromCenter=False, showCrosshair=True) + + # 幅(bbox[2]) または 高さ(bbox[3]) が 0 の場合 + # ('c'キーが押された、または未選択のままEnterが押された場合) + if bbox[2] == 0 or bbox[3] == 0: + print("領域がリセットされました。やり直します。") + print("もう一度マウスをドラッグして対象を囲み、Enterキーを押してください。") + # continueによってループの先頭に戻り、再度selectROIを実行する + continue + else: + # 正しく領域が選択されたらループを抜けてトラッキング処理へ進む + print("領域が確定しました。トラッキングを開始します。") + break + + # --- トラッカーの生成と初期化 --- + # 拡張モジュールに含まれる高精度なトラッカー「CSRT」を生成 + # ※OpenCVのバージョンによっては legacy に分類されるため、try-exceptで安全に呼び出す + try: + tracker = cv2.TrackerCSRT_create() + except AttributeError: + tracker = cv2.legacy.TrackerCSRT_create() + + # 最初のフレームと、選択した領域(bbox)を渡してトラッカーに学習(初期化)させる + tracker.init(frame, bbox) + + print("追跡中... 終了するには 'q' キーを押してください。") + + # --- トラッキングのループ処理 --- + while True: + ret, frame = cap.read() + if not ret: + break + + # 新しいフレームをトラッカーに渡し、対象がどこに移動したか推測させる + # success: 追跡成功(True) / 失敗(False) + # bbox: 新しい座標とサイズ (x, y, w, h) + success, bbox = tracker.update(frame) + + if success: + # 追跡成功時:新しい座標を整数に変換して青い枠線を描画 + p1 = (int(bbox[0]), int(bbox[1])) + p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3])) + cv2.rectangle(frame, p1, p2, (255, 0, 0), 2, 1) + cv2.putText(frame, "Tracking", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2) + else: + # 追跡失敗時(画面外に出た、何かの裏に完全に隠れた等):赤い警告文を表示 + cv2.putText(frame, "Lost", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) + + # 結果の表示 + cv2.imshow("Tracking", frame) + + # 'q' キーで終了 + if cv2.waitKey(1) & 0xFF == ord('q'): + break + + # 終了処理 + cap.release() + cv2.destroyAllWindows() \ No newline at end of file diff --git a/3_1_resize_rotate.py b/3_1_resize_rotate.py new file mode 100644 index 0000000..07ab223 --- /dev/null +++ b/3_1_resize_rotate.py @@ -0,0 +1,41 @@ +# 実験課題1 +# 3.1 画像サイズ変換・画像の回転 + +import cv2 + +# 画像の読み込み(任意のカラー画像を用意し、ファイル名を指定してください) +image_path = 'sample.jpg' +img = cv2.imread(image_path) + +if img is None: + print("画像を読み込めませんでした。ファイルパスを確認してください。") +else: + # --- 画像サイズ変換 --- + # 元画像の高さと幅を取得 + height, width = img.shape[:2] + + # 縦横を1/2のサイズに計算 + new_width = width // 2 + new_height = height // 2 + + # 画像のサイズを変更 + resized_img = cv2.resize(img, (new_width, new_height)) + + # --- 画像の回転 --- + # 回転の中心座標を計算(画像の中心) + center = (width // 2, height // 2) + + # 45度回転するための変換行列を作成(スケールは1.0でそのまま) + rotation_matrix = cv2.getRotationMatrix2D(center, 45, 1.0) + + # アフィン変換を適用して画像を回転 + rotated_img = cv2.warpAffine(img, rotation_matrix, (width, height)) + + # --- 結果の表示 --- + cv2.imshow('Original Image', img) + cv2.imshow('Resized Image (1/2)', resized_img) + cv2.imshow('Rotated Image (45 degrees)', rotated_img) + + # キー入力待ち(任意のキーを押すとウィンドウが閉じる) + cv2.waitKey(0) + cv2.destroyAllWindows() \ No newline at end of file diff --git a/3_2_grayscale.py b/3_2_grayscale.py new file mode 100644 index 0000000..d415b88 --- /dev/null +++ b/3_2_grayscale.py @@ -0,0 +1,23 @@ +# 実験課題2 +# 3.2 グレースケール化 + +import cv2 + +# 画像の読み込み(カラー画像を用意し、ファイル名を指定してください) +image_path = 'sample.jpg' +img = cv2.imread(image_path) + +if img is None: + print("画像を読み込めませんでした。ファイルパスを確認してください。") +else: + # --- グレースケール化 --- + # BGR形式のカラー画像をグレースケールに変換 + gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + + # --- 結果の表示 --- + cv2.imshow('Original Color Image', img) + cv2.imshow('Grayscale Image', gray_img) + + # キー入力待ち + cv2.waitKey(0) + cv2.destroyAllWindows() \ No newline at end of file diff --git a/3_3_binarization.py b/3_3_binarization.py new file mode 100644 index 0000000..386f6c6 --- /dev/null +++ b/3_3_binarization.py @@ -0,0 +1,31 @@ +# 実験課題3 +# 3.3 2値化 + +import cv2 + +# 画像の読み込み(3.2と同じ画像を使用) +image_path = 'sample.jpg' + +# 第2引数に 0 (cv2.IMREAD_GRAYSCALE) を指定し、最初からグレースケールとして読み込む +gray_img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) + +if gray_img is None: + print("画像を読み込めませんでした。ファイルパスを確認してください。") +else: + # --- 2値化処理 --- + # 閾値(自身の画像に合わせて0〜255の間で適切な値に調整してください) + threshold_value = 127 + # 閾値を超えた画素に割り当てる値(白 = 255) + max_value = 255 + + # 2値化を実行 + # ret には使用された閾値が、binary_img には2値化後の画像が代入される + ret, binary_img = cv2.threshold(gray_img, threshold_value, max_value, cv2.THRESH_BINARY) + + # --- 結果の表示 --- + cv2.imshow('Original Grayscale Image', gray_img) + cv2.imshow('Binarized Image (Threshold: 127)', binary_img) + + # キー入力待ち + cv2.waitKey(0) + cv2.destroyAllWindows() \ No newline at end of file diff --git a/3_4_roi.py b/3_4_roi.py new file mode 100644 index 0000000..bba14be --- /dev/null +++ b/3_4_roi.py @@ -0,0 +1,34 @@ +# 実験課題4 +# 3.4 ROIの利用 + +import cv2 + +# 画像の読み込み(任意の画像を用意してください) +image_path = 'sample.jpg' +img = cv2.imread(image_path) + +if img is None: + print("画像を読み込めませんでした。ファイルパスを確認してください。") +else: + # 画像の高さ、幅を取得 + height, width = img.shape[:2] + + # --- ROI(関心領域)の指定 --- + # 切り出す領域の開始位置と終了位置を計算(例として、画像の中心部分を切り出し) + start_y = height // 4 + end_y = height * 3 // 4 + start_x = width // 4 + end_x = width * 3 // 4 + + # --- 画像の切り出し --- + # NumPy配列のスライス機能を使用して、指定した範囲を切り出す + # 指定順序は [yの開始:yの終了, xの開始:xの終了] + roi_img = img[start_y:end_y, start_x:end_x] + + # --- 結果の表示 --- + cv2.imshow('Original Image', img) + cv2.imshow('ROI (Region of Interest)', roi_img) + + # キー入力待ち + cv2.waitKey(0) + cv2.destroyAllWindows() \ No newline at end of file diff --git a/3_5_edge.py b/3_5_edge.py new file mode 100644 index 0000000..cdb2eb9 --- /dev/null +++ b/3_5_edge.py @@ -0,0 +1,43 @@ +# 実験課題5 +# 3.5 エッジ処理 + +import cv2 + +# 画像の読み込み(エッジ検出は通常グレースケール画像に対して行います) +image_path = 'sample.jpg' +img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) + +if img is None: + print("画像を読み込めませんでした。ファイルパスを確認してください。") +else: + # --- Sobel(ソーベル)フィルタ --- + # X方向の勾配(縦のエッジ)とY方向の勾配(横のエッジ)を計算 + # 負の勾配を保持するため、出力データ型を cv2.CV_64F に指定 + sobel_x = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3) + sobel_y = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3) + + # 絶対値を取り、表示可能な8ビット符号なし整数(0〜255)に変換 + sobel_x_abs = cv2.convertScaleAbs(sobel_x) + sobel_y_abs = cv2.convertScaleAbs(sobel_y) + + # X方向とY方向の画像を1:1の割合で合成して全体のエッジ画像を作成 + sobel_combined = cv2.addWeighted(sobel_x_abs, 0.5, sobel_y_abs, 0.5, 0) + + # --- Laplacian(ラプラシアン)フィルタ --- + # 2次微分を用いて全方向のエッジを同時に検出 + laplacian = cv2.Laplacian(img, cv2.CV_64F) + laplacian_abs = cv2.convertScaleAbs(laplacian) + + # --- Canny(キャニー)法 --- + # ノイズ除去と2つの閾値処理を組み合わせた、より高精度なエッジ検出アルゴリズム + canny = cv2.Canny(img, 50, 150) + + # --- 結果の表示 --- + cv2.imshow('Original Grayscale', img) + cv2.imshow('Sobel Edge', sobel_combined) + cv2.imshow('Laplacian Edge', laplacian_abs) + cv2.imshow('Canny Edge', canny) + + # キー入力待ち + cv2.waitKey(0) + cv2.destroyAllWindows() \ No newline at end of file diff --git a/kadai6.py b/3_6_color_extraction.py similarity index 92% rename from kadai6.py rename to 3_6_color_extraction.py index 1270bd2..e44c603 100644 --- a/kadai6.py +++ b/3_6_color_extraction.py @@ -1,5 +1,5 @@ # 実験課題6 -# 色領域抽出 +# 3.6 色領域抽出 import cv2 import numpy as np @@ -18,7 +18,7 @@ else: # --- 肌色の範囲を指定 (HSV) --- # OpenCVにおけるH(色相)は0〜179、S(彩度)とV(明度)は0〜255 # ※画像の色合いや照明条件に合わせて微調整が必要です - lower_skin = np.array([0, 20, 70]) # 下限値 (H, S, V) + lower_skin = np.array([0, 0, 70]) # 下限値 (H, S, V) upper_skin = np.array([20, 255, 255]) # 上限値 (H, S, V) # --- マスク画像の作成 --- diff --git a/3_7_morphology.py b/3_7_morphology.py new file mode 100644 index 0000000..6182d76 --- /dev/null +++ b/3_7_morphology.py @@ -0,0 +1,44 @@ +# 実験課題7 +# 3.7 膨張・収縮 + +import cv2 +import numpy as np + +# 3.6の画像(色領域を抽出した画像)を準備するための前処理 +image_path = 'person.jpg' +img = cv2.imread(image_path) + +if img is None: + print("画像を読み込めませんでした。ファイルパスを確認してください。") +else: + # 3.6の処理(肌色領域の抽出)を再現 + hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) + lower_skin = np.array([0, 0, 70]) + upper_skin = np.array([20, 255, 255]) + skin_mask = cv2.inRange(hsv_img, lower_skin, upper_skin) + extracted_img = cv2.bitwise_and(img, img, mask=skin_mask) + + # --- 膨張・収縮のための構造要素(カーネル)の定義 --- + # 5x5の正方形のカーネルを作成 + kernel = np.ones((5, 5), np.uint8) + + # --- ① 収縮 3回 → 膨張 3回(オープニング処理) --- + # まず収縮(erode)を3回実行 + eroded_first = cv2.erode(extracted_img, kernel, iterations=3) + # その後、膨張(dilate)を3回実行 + seq_opening = cv2.dilate(eroded_first, kernel, iterations=3) + + # --- ② 膨張 3回 → 収縮 3回(クロージング処理) --- + # まず膨張(dilate)を3回実行 + dilated_first = cv2.dilate(extracted_img, kernel, iterations=3) + # その後、収縮(erode)を3回実行 + seq_closing = cv2.erode(dilated_first, kernel, iterations=3) + + # --- 結果の表示 --- + cv2.imshow('Original Extracted Image (3.6)', extracted_img) + cv2.imshow('Sequence 1: Erosion 3 -> Dilation 3', seq_opening) + cv2.imshow('Sequence 2: Dilation 3 -> Erosion 3', seq_closing) + + # キー入力待ち + cv2.waitKey(0) + cv2.destroyAllWindows() \ No newline at end of file diff --git a/3_8_webcam.py b/3_8_webcam.py new file mode 100644 index 0000000..1e203de --- /dev/null +++ b/3_8_webcam.py @@ -0,0 +1,38 @@ +# 実験課題8 +# 3.8 Webカメラ映像のキャプチャと表示 + +import cv2 + +# Webカメラのデバイスを初期化(引数の 0 は標準のカメラデバイスを指します) +cap = cv2.VideoCapture(0) + +# カメラが正常に起動・接続できたかを確認 +if not cap.isOpened(): + print("カメラを開けませんでした。カメラの接続や権限を確認してください。") +else: + print("カメラ映像の表示を開始します。終了するには 'q' キーを押してください。") + + # 映像は「連続した静止画(フレーム)」なので、無限ループで取得し続けます + while True: + # カメラから1フレーム(1枚の画像)を読み込む + # ret には取得成功の可否(True/False)、frame には画像データ(NumPy配列)が入ります + ret, frame = cap.read() + + # 画像が正しく取得できなかった場合はループを終了 + if not ret: + print("フレームを正常に取得できませんでした。") + break + + # 取得したフレームを画面に表示 + cv2.imshow('Webcam Capture', frame) + + # 1ミリ秒だけキー入力を待機する + # もし入力されたキーが 'q' であれば、ループを抜けて終了処理へ進む + if cv2.waitKey(1) & 0xFF == ord('q'): + break + + # --- 終了処理 --- + # カメラデバイスを解放(プログラムからの占有を解除) + cap.release() + # 全てのウィンドウを閉じる + cv2.destroyAllWindows() \ No newline at end of file diff --git a/3_9_face_detection.py b/3_9_face_detection.py new file mode 100644 index 0000000..409dfbf --- /dev/null +++ b/3_9_face_detection.py @@ -0,0 +1,67 @@ +# 実験課題9 +# 3.9 顔検出 + +import cv2 + +# --- カスケード分類器(学習済みデータ)の読み込み --- +# OpenCVに標準で用意されている顔検出用のXMLファイルを指定 +cascade_path = cv2.data.haarcascades + 'haarcascade_frontalface_default.xml' +face_cascade = cv2.CascadeClassifier(cascade_path) + +# Webカメラの初期化 +cap = cv2.VideoCapture(0) + +if not cap.isOpened(): + print("カメラを開けませんでした。") +else: + print("顔検出を開始します。'q' キーで終了します。") + + while True: + ret, frame = cap.read() + if not ret: + print("フレームを取得できませんでした。") + break + + # 3.91 顔検出の精度と処理速度向上のため、グレースケール画像を作成 + gray_img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + + # グレースケール画像から顔を検出 + faces = face_cascade.detectMultiScale( + gray_img, + scaleFactor=1.1, + minNeighbors=5, + minSize=(30, 30) + ) + + # 検出されたすべての顔に対してループ処理 + for (x, y, w, h) in faces: + + # --- 3.92 顔を隠す処理(別の画像の貼り付け) --- + # 貼り付けたい画像(例: 'mask.jpg')を読み込んで顔の領域に上書きします + mask_img = cv2.imread('mask.jpg') + + if mask_img is not None: + # 読み込んだ画像を、検出された顔の横幅(w)と縦幅(h)と同じサイズにリサイズ + mask_resized = cv2.resize(mask_img, (w, h)) + # NumPyのスライス機能(ROI)を使い、元のフレームの顔領域を隠し用画像で上書き + frame[y:y + h, x:x + w] = mask_resized + else: + # 'mask.jpg' が見つからない場合は、代わりに顔領域を黒い矩形で塗りつぶして隠す(値を0にする) + # 資料の「顔を隠すような処理」を代替実行します + frame[y:y + h, x:x + w] = 0 + + # --- 3.91 顔部分を矩形で囲む --- + # 隠す処理の後に矩形を描画することで、枠線が隠されずに上から表示されます + # 引数: (対象画像, 開始座標, 終了座標, 色(BGR), 線の太さ) + cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) + + # 結果を画面に表示 + cv2.imshow('Face Detection & Masking', frame) + + # 'q' キーが押されたら終了 + if cv2.waitKey(1) & 0xFF == ord('q'): + break + + # 後片付け + cap.release() + cv2.destroyAllWindows() \ No newline at end of file diff --git a/kadai1.py b/kadai1.py deleted file mode 100644 index bb496a2..0000000 --- a/kadai1.py +++ /dev/null @@ -1,36 +0,0 @@ -# 実験課題1 -# 画像サイズ変換・画像の回転 - -import cv2 - -# 画像の読み込み(任意のカラー画像を用意し、ファイル名を指定してください) -image_path = 'cat.jfif' -img = cv2.imread(image_path) - -height, width = img.shape[:2] - -# 縦横を1/2のサイズに計算 -new_width = width // 2 -new_height = height // 2 - -# 画像のサイズを変更 -resized_img = cv2.resize(img, (new_width, new_height)) - -# --- 画像の回転 --- -# 回転の中心座標を計算(画像の中心) -center = (width // 2, height // 2) - -# 45度回転するための変換行列を作成(スケールは1.0でそのまま) -rotation_matrix = cv2.getRotationMatrix2D(center, 45, 1.0) - -# アフィン変換を適用して画像を回転 -rotated_img = cv2.warpAffine(img, rotation_matrix, (width, height)) - -# --- 結果の表示 --- -cv2.imshow('Original Image', img) -cv2.imshow('Resized Image (1/2)', resized_img) -cv2.imshow('Rotated Image (45 degrees)', rotated_img) - -# キー入力待ち(任意のキーを押すとウィンドウが閉じる) -cv2.waitKey(0) -cv2.destroyAllWindows() diff --git a/kadai2.py b/kadai2.py deleted file mode 100644 index 8829642..0000000 --- a/kadai2.py +++ /dev/null @@ -1,20 +0,0 @@ -# 実験課題2 -# グレースケール化 - -import cv2 - -# 画像の読み込み(カラー画像を用意し、ファイル名を指定してください) -image_path = 'cat.jfif' -img = cv2.imread(image_path) - -# --- グレースケール化 --- -# BGR形式のカラー画像をグレースケールに変換 -gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) - -# --- 結果の表示 --- -cv2.imshow('Original Color Image', img) -cv2.imshow('Grayscale Image', gray_img) - -# キー入力待ち -cv2.waitKey(0) -cv2.destroyAllWindows() \ No newline at end of file diff --git a/kadai3.py b/kadai3.py deleted file mode 100644 index aa08537..0000000 --- a/kadai3.py +++ /dev/null @@ -1,28 +0,0 @@ -# 実験課題3 -# 2値化 - -import cv2 - -# 画像の読み込み(3.2と同じ画像を使用) -image_path = 'cat.jfif' - -# 第2引数に 0 (cv2.IMREAD_GRAYSCALE) を指定し、最初からグレースケールとして読み込む -gray_img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) - -# --- 2値化処理 --- -# 閾値(自身の画像に合わせて0〜255の間で適切な値に調整してください) -threshold_value = 127 -# 閾値を超えた画素に割り当てる値(白 = 255) -max_value = 255 - -# 2値化を実行 -# ret には使用された閾値が、binary_img には2値化後の画像が代入される -ret, binary_img = cv2.threshold(gray_img, threshold_value, max_value, cv2.THRESH_BINARY) - -# --- 結果の表示 --- -cv2.imshow('Original Grayscale Image', gray_img) -cv2.imshow('Binarized Image (Threshold: 127)', binary_img) - -# キー入力待ち -cv2.waitKey(0) -cv2.destroyAllWindows() \ No newline at end of file diff --git a/kadai4.py b/kadai4.py deleted file mode 100644 index d773411..0000000 --- a/kadai4.py +++ /dev/null @@ -1,31 +0,0 @@ -# 実験課題4 -# ROIの利用 - -import cv2 - -# 画像の読み込み(任意の画像を用意してください) -image_path = 'cat.jfif' -img = cv2.imread(image_path) - -# 画像の高さ、幅を取得 -height, width = img.shape[:2] - -# --- ROI(関心領域)の指定 --- -# 切り出す領域の開始位置と終了位置を計算(例として、画像の中心部分を切り出し) -start_y = height // 4 -end_y = height * 3 // 4 -start_x = width // 4 -end_x = width * 3 // 4 - -# --- 画像の切り出し --- -# NumPy配列のスライス機能を使用して、指定した範囲を切り出す -# 指定順序は [yの開始:yの終了, xの開始:xの終了] -roi_img = img[start_y:end_y, start_x:end_x] - -# --- 結果の表示 --- -cv2.imshow('Original Image', img) -cv2.imshow('ROI (Region of Interest)', roi_img) - -# キー入力待ち -cv2.waitKey(0) -cv2.destroyAllWindows() \ No newline at end of file diff --git a/kadai5.py b/kadai5.py deleted file mode 100644 index bedab97..0000000 --- a/kadai5.py +++ /dev/null @@ -1,40 +0,0 @@ -# 実験課題5 -# 3.5 エッジ処理 - -import cv2 - -# 画像の読み込み(エッジ検出は通常グレースケール画像に対して行います) -image_path = 'cat.jfif' -img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) - -# --- Sobel(ソーベル)フィルタ --- -# X方向の勾配(縦のエッジ)とY方向の勾配(横のエッジ)を計算 -# 負の勾配を保持するため、出力データ型を cv2.CV_64F に指定 -sobel_x = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3) -sobel_y = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3) - -# 絶対値を取り、表示可能な8ビット符号なし整数(0〜255)に変換 -sobel_x_abs = cv2.convertScaleAbs(sobel_x) -sobel_y_abs = cv2.convertScaleAbs(sobel_y) - -# X方向とY方向の画像を1:1の割合で合成して全体のエッジ画像を作成 -sobel_combined = cv2.addWeighted(sobel_x_abs, 0.5, sobel_y_abs, 0.5, 0) - -# --- Laplacian(ラプラシアン)フィルタ --- -# 2次微分を用いて全方向のエッジを同時に検出 -laplacian = cv2.Laplacian(img, cv2.CV_64F) -laplacian_abs = cv2.convertScaleAbs(laplacian) - -# --- Canny(キャニー)法 --- -# ノイズ除去と2つの閾値処理を組み合わせた、より高精度なエッジ検出アルゴリズム -canny = cv2.Canny(img, 50, 150) - -# --- 結果の表示 --- -cv2.imshow('Original Grayscale', img) -cv2.imshow('Sobel Edge', sobel_combined) -cv2.imshow('Laplacian Edge', laplacian_abs) -cv2.imshow('Canny Edge', canny) - -# キー入力待ち -cv2.waitKey(0) -cv2.destroyAllWindows() \ No newline at end of file diff --git a/mask.jpg b/mask.jpg new file mode 100644 index 0000000..566ba77 Binary files /dev/null and b/mask.jpg differ diff --git a/person.jpg b/person.jpg new file mode 100644 index 0000000..8b21711 Binary files /dev/null and b/person.jpg differ diff --git a/cat.jfif b/sample.jpg similarity index 100% rename from cat.jfif rename to sample.jpg