機械学習 映像の物体判定

#webカメラ取り込み

import cv2
import numpy as np

# webカメラが入力を開始
cap = cv2.VideoCapture(0)
while True:
    #カメラの画像を読み込む
    _, frame = cap.read()
    
    #画像を縮小表示する
    frame = cv2.resize(frame, (500, 300))
    
    #ウィンドウに画像を出力
    cv2.imshow('OpneCV Web Camera', frame)
    
    #ESC27かEnter13キーがおされたらループを抜ける
    k = cv2.waitKey(1) # 1msec確認
    if k == 27 or k == 13: break
        
cap.release() # カメラを開放
cv2.destroyAllWindows() # windowを破壊
# 赤成分だけにする

import cv2
import numpy as np

# webカメラが入力を開始
cap = cv2.VideoCapture(0)
while True:
    #カメラの画像を読み込む
    _, frame = cap.read()
    
    #画像を縮小表示する
    frame = cv2.resize(frame, (500, 300))
    
    #青色と緑色の成分を0に
    frame[:, :, 0] = 0
    frame[:, :, 1] = 0
    
    #ウィンドウに画像を出力
    cv2.imshow('RED Camera', frame)
    
    #ESC27かEnter13キーがおされたらループを抜ける
    k = cv2.waitKey(1) # 1msec確認
    if k == 27 or k == 13: break
        
cap.release() # カメラを開放
cv2.destroyAllWindows() # windowを破壊
# HSV色空間に対応する

import cv2
import numpy as np

# webカメラが入力を開始
cap = cv2.VideoCapture(0)
while True:
    # カメラの画像を読み込む
    _, frame = cap.read()
    
    # 画像を縮小表示する
    frame = cv2.resize(frame, (500, 300))
    
    # 色空間をHSVに変換
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV_FULL)
    
    # HSVを分割する
    h = hsv[:, :, 0]
    s = hsv[:, :, 1]
    v = hsv[:, :, 2]
    
    # 赤色っぽい色を持つ画素だけを抽出
    img = np.zeros(h.shape, dtype=np.uint8)
    img[((h < 50) | (h > 200)) & (s > 100)] = 255
    
    # ウィンドウに画像を出力
    cv2.imshow('RED Camera', img)  # 修正: frame から img に変更
    
    # ESCかEnterキーが押されたらループを抜ける
    k = cv2.waitKey(1)  # 1msec確認
    if k == 27 or k == 13: 
        break
        
cap.release()  # カメラを開放
cv2.destroyAllWindows()  # windowを破壊
#画像に動きがあった部分を検出

import cv2

cap = cv2.VideoCapture(0)
img_last = None
green = (0, 255, 0)

while True:
    # 画像取得
    ret, frame = cap.read()
    if not ret:  # 画像が読み込めなかったらスキップ
        continue
    frame = cv2.resize(frame, (500, 300))
    # 白黒画像に変換
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (9, 9), 0)
    img_b = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)[1]
    # 差分を確認する
    if img_last is None:
        img_last = img_b
        continue
    frame_diff = cv2.absdiff(img_last, img_b)
    
    # OpenCVのバージョンに応じてcntsの取得方法を変える
    cnts, _ = cv2.findContours(frame_diff, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2:]
    
    # 差分があった点を画面に描く
    for pt in cnts:
        x, y, w, h = cv2.boundingRect(pt)
        if w < 30: continue
        cv2.rectangle(frame, (x, y), (x+w, y+h), green, 2)
    # 今回のフレームを保存
    img_last = img_b
    # 画面に表示
    cv2.imshow("Diff Camera", frame)
    cv2.imshow("diff data", frame_diff)
    if cv2.waitKey(1) == 13: break

cap.release()
cv2.destroyAllWindows()

    
# 動画ファイルの書き出し

import cv2
import numpy as np

# カメラからの入力を開始
cap = cv2.VideoCapture(0)

# 動画書き出し用のオブジェクトを生成
fmt = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
fps = 20.0
size = (640, 360)
writer = cv2.VideoWriter('test.m4v', fmt, fps, size)

while True:
    ret, frame = cap.read()
    if not ret:
        print("フレームを取得できませんでした。")
        break  # フレームが正常に読み込めなかったらループを抜ける
    
    # 画像を縮小
    frame = cv2.resize(frame, size)
    
    # 画像を出力
    writer.write(frame)
    
    # ウィンドウ上にも表示
    cv2.imshow('frame', frame)
    
    # Enterキーが押されたらループを抜ける
    if cv2.waitKey(1) == 13: break

# 正しいメソッド名に修正
writer.release()
cap.release()
cv2.destroyAllWindows()
# 熱帯魚の写真を取り出す

import cv2, os

img_last = None
no = 0
save_dir = "./exfish"
os.mkdir(save_dir)

#動画フィあるから入力を開始
cap = cv2.VideoCapture("fish.mp4")
while True:
    #画像取得
    is_ok, frame = cap.read()
    if not is_ok: break
    frame = cv2.resize(frame, (640 ,360))
    #白黒画像に変換
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (15, 15), 0)
    img_b = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)[1]
    #差分確認
    if not img_last is None:
        frame_diff = cv2.absdiff(img_last, img_b)
        cnts = cv2.findContours(frame_diff,cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]
    # 差分があった領域をファイルに出力
    for pt in cnts:
        x, y, w, h = cv2.boundingRect(pt)
        if w < 100 or w > 500: continue
        #抽出した領域を画像として保存
        imgex = frame[y:y+h, x:x+w]
        outfile = save_dir + "/" + str(no) + ".jpg"
        cv2.imwrite(outfile, imgex)
        no += 1
    img_last = img_b
cap.release()
print("ok")
# fish_train.py

import cv2
import os, glob, pickle
from sklearn.model_selection import train_test_split
from sklearn import datasets, metrics
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

# 画像の学習サイズやパスを指定
image_size = (64, 32)
path = os.getcwd()  # 現在の作業ディレクトリを取得
path_fish = os.path.join(path, 'fish')
path_nofish = os.path.join(path, 'nofish')
x = []  # 画像データ
y = []  # ラベル

# 画像データを読み込んで配列に追加
def read_dir(path, label):
    files = glob.glob(path + "/*.jpg")
    for f in files:
        img = cv2.imread(f)
        img = cv2.resize(img, image_size)
        img_data = img.reshape(-1,)
        x.append(img_data)
        y.append(label)

# 画像データを読み込む
read_dir(path_nofish, 0)
read_dir(path_fish, 1)

# データを学習用とテスト用に分割する
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)

# データを学習
clf = RandomForestClassifier()
clf.fit(x_train, y_train)

# 精度の確認
y_pred = clf.predict(x_test)
print(accuracy_score(y_test, y_pred))

# データを保存
with open("fish.pkl", "wb") as fp:
    pickle.dump(clf, fp)
0.9166666666666666
# fishvideo_fined,py 動画を解析して魚を抽出

import cv2, os, copy, pickle

# 学習済みデータを取り出す
with open("fish.pkl", "rb") as fp:
    clf = pickle.load(fp)
output_dir = "./bestshot"
img_last = None
fish_th = 3
count = 0
frame_count = 0
if not os.path.isdir(output_dir): os.mkdir(output_dir)
    
# 動画ファイルから入力を開始
cap = cv2.VideoCapture("fish.mp4")
while True:
    # 画像を取得
    is_ok, frame = cap.read()
    if not is_ok: break
    frame = cv2.resize(frame, (640, 360))
    frame2 = copy.copy(frame)
    frame_count += 1
    # 前フレームと比較するために白黒に変換
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (15, 15), 0)
    img_b = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)[1]
    if img_last is not None:
        # 差分を得る
        frame_diff = cv2.absdiff(img_last, img_b)
        # OpenCVのバージョンに応じてcntsの取得方法を変える
        cnts, _ = cv2.findContours(frame_diff, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2:]
        # 差分領域に魚が映っているか調べる
        fish_count = 0
        for pt in cnts:
            x, y, w, h = cv2.boundingRect(pt)
            if w < 100 or w > 500: continue
            # 抽出した領域に魚が映っているか確認
            imgex = frame[y:y+h, x:x+w]
            imagex = cv2.resize(imgex, (64, 32))
            image_data = imagex.reshape(-1,)
            pred_y = clf.predict([image_data])
            if pred_y[0] == 1:
                fish_count += 1  # 修正: += 1 に
                cv2.rectangle(frame2, (x, y), (x+w, y+h), (0, 255, 0), 2)
        # 魚が映っているか?
        if fish_count > fish_th:
            fname = os.path.join(output_dir, "fish{}.jpg".format(count))  # 修正: ファイルパスの組み立て
            cv2.imwrite(fname, frame)
            count += 1
    cv2.imshow('FISH!', frame2)
    if cv2.waitKey(1) == 13: break
    img_last = img_b

cap.release()
cv2.destroyAllWindows()
print("ok", count, "/", frame_count)

ok 125 / 1990
タイトルとURLをコピーしました