OpenCV (4) - 画像の特徴とターゲット検出

コースの概要:

目次

1. 画像の特徴を理解する

2. 形状特徴の説明

2.1 HOGの原理

2.2 ハリス

2.3 シフト

3. 質感の特徴

4. テンプレートマッチング

5. 顔検出


1. 画像の特徴を理解する

画像の特徴は、一意で追跡および比較が容易な画像内の特定のテンプレートまたは特定の構造です。

  • 画像特徴の抽出とマッチングはコンピュータ ビジョンにおける重要な問題であり、ターゲット検出、オブジェクト認識、3D 再構成、画像レジストレーション、画像理解などの特定のアプリケーションで重要な役割を果たします。
  • 画像特徴には、主に画像の色特徴テクスチャ特徴形状特徴空間関係特徴が含まれます。

(1) 色の特性

  • カラー特徴は、画像または画像領域に対応するシーンの表面特性を記述するグローバル特徴です。
  • 色の特徴の記述方法
    • カラーヒストグラム
    • 色空間
    • 色の分布

(2) 質感の特徴

  • テクスチャ特徴も一種のグローバル特徴であり、画像または画像領域に対応するシーンの表面特性も記述します。しかし、テクスチャは物体の表面の特性にすぎないため、物体の本質的な特性を完全に反映することはできず、テクスチャ特徴だけを使用して高度な画像コンテンツを取得することは不可能です。

 (3) 形状の特徴

  • 形状特徴量の表現方法には、輪郭特徴量と面特徴量の 2 種類があります画像の輪郭特徴は主にオブジェクトの外側の境界を対象としていますが、画像の領域特徴は画像内の局所的な形状特徴を表します。

 (4) 空間関係の特徴

  • 空間関係特徴とは、画像内に分割された複数のターゲット間の相互の空間位置または相対方向関係を指します。
  • これらの関係は、結合/隣接関係、重複/オーバーラップ関係、包含/独立関係などに分類することもできます。

2. 形状特徴の説明

2.1 HOGの原理

HOG特徴抽出

  • HOG (Oriented Gradients のヒストグラム) 機能は、コンピューター ビジョンおよび画像処理におけるオブジェクト検出に使用される特徴記述子です。(主に形状特徴を抽出するために使用されます)
  • 画像の局所領域勾配ヒストグラムを計算してカウントすることで特徴を形成します。
  • SVM 分類器と組み合わせた Hog 特徴は、画像認識、特に歩行者検出で広く使用され、大きな成功を収めています。(HOG を使用して特徴を抽出し、SVM を使用して分類します)
  • 主な考え方: 画像では、ターゲットの形状はエッジの勾配または方向密度分布によって適切に表現できます。

HOG の実装プロセス

  • グレースケール(画像を x、y、z (グレースケール) の 3 次元画像として考えてください)
  • ガンマ補正手法を使用して入力画像の色空間を標準化する(正規化)
  • 画像の各ピクセルの勾配 (大きさと方向の両方) を計算します。
  • 画像を小さなセルに分割します
  • 各セルの勾配ヒストグラム (異なる勾配の数) をカウントして、セルの記述子を取得します。
  • いくつかのセルごとに結合してブロックを作成し、ブロック記述子を取得します。
  • イメージ画像内のすべてのブロックの HOG 特徴記述子を接続して、HOG 特徴を取得します (特徴ベクトルは、ターゲットの検出または分類に使用される特徴です)。
#=================================HOG 特征===============================#
# flag = 0
flag = 1
if flag == 1:
    # 判断矩形i是否完全包含在矩形o中
    def is_inside(o, i):
        ox, oy, ow, oh = o
        ix, iy, iw, ih = i
        return ox > ix and oy > iy and ox + ow < ix + iw and oy + oh < iy + ih
    # 对人体绘制颜色框
    def draw_person(image, person):
        x, y, w, h = person
        cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 255), 2)
    img = cv2.imread("people.jpg")
    hog = cv2.HOGDescriptor()  # 启动检测器对象
    hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())  # 指定检测器类型为人体
    found, w = hog.detectMultiScale(img,0.1,(2,2)) # 加载并检测图像
    print(found)
    print(w)

    # 丢弃某些完全被其它矩形包含在内的矩形
    found_filtered = []
    for ri, r in enumerate(found):
        for qi, q in enumerate(found):
            if ri != qi and is_inside(r, q):
                break
        else:
            found_filtered.append(r)
            print(found_filtered)
    # 对不包含在内的有效矩形进行颜色框定
    for person in found_filtered:
        draw_person(img, person)
    cv2.imshow("people detection", img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

2.2 ハリス

(1) ハリス角検出

  • コーナー ポイント: 現実世界では、コーナー ポイントはオブジェクトの角、道路の交差点、T 字路などに対応します。画像解析の観点から見ると、コーナー ポイントの定義には 2 つの定義があります。
    • コーナーポイントは 2 つのエッジの交差点になる場合があります
    • コーナーポイントは、近傍に 2 つの主な方向がある特徴点です。
  • コーナーの計算方法:
    • 前者は画像の端まで計算するため、計算量が多く、画像の局所的な変化が結果に与える影響が大きくなります。
    • 後者の方法は、画像のグレースケールに基づいて、点の曲率と勾配を計算することでコーナーを検出します。

  • コーナーポイントの特徴:
    • 等高線間の交差
    • 同じシーンであれば、見る角度が変わっても安定した特性を持つことが多い
    • この点の近傍のピクセルは、勾配の方向および勾配の大きさの両方において大きな変化を有する。
  • パフォーマンスが向上したコーナー:
    • 画像内の「実際の」コーナーを検出します
    • 正確な位置決め性能
    • 高いリピート検出率
    • 耐ノイズ性
    • より高い計算効率

(2) ハリス導入プロセス

  •  画像の X 方向と Y 方向の勾配を計算します。
  • 画像の 2 方向の勾配の積を計算します。
  • ガウス関数を使用して 3 つにガウス重み付けを実行し、行列 M の A、B、C を生成します。
  • 各ピクセルのハリス応答値 R を計算し、一定のしきい値 t 未満の場合は R をゼロに設定します。
  • 非最大値抑制は 3×3 または 5×5 の近傍で実行され、極大点は画像内のコーナー点になります。

(3) ハリスコードの適用

Open の関数 cv2.cornerHarris() はコーナー検出に使用できます。

パラメータは次のとおりです。

  • img: データ型が float32 である入力画像
  • blockSize: コーナー検出で考慮されるフィールドのサイズ
  • ksize: ソーベル導出で使用されるウィンドウ サイズ
  • k: Harris コーナー検出式の自由パラメータ、値パラメータは [0.04, 0.06]

#=================================Harris 角点===============================#
# flag = 0
flag = 1
if flag == 1:
    img = cv2.imread('harris2.png')
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    gray = np.float32(gray)
    dst_block9_ksize19 = cv2.cornerHarris(gray, 9, 19, 0.04)
    img1 = np.copy(img)
    img1[dst_block9_ksize19 > 0.01 * dst_block9_ksize19.max()] = [0, 0, 255]

    dst_block5_ksize19 = cv2.cornerHarris(gray, 5, 19, 0.04)
    img2 = np.copy(img)
    img2[dst_block5_ksize19 > 0.01 * dst_block5_ksize19.max()] = [0, 0, 255]

    dst_block9_ksize5 = cv2.cornerHarris(gray, 9, 5, 0.04)
    img3 = np.copy(img)
    img3[dst_block9_ksize5 > 0.01 * dst_block9_ksize5.max()] = [0, 0, 255]

    dst_block9_ksize31 = cv2.cornerHarris(gray, 9, 31, 0.04)
    img4 = np.copy(img)
    img4[dst_block9_ksize31 > 0.01 * dst_block9_ksize31.max()] = [0, 0, 255]

    dst_block9_ksize19_k6 = cv2.cornerHarris(gray, 9, 19, 0.06)
    img5 = np.copy(img)
    img5[dst_block9_ksize19_k6 > 0.01 * dst_block9_ksize19_k6.max()] = [0, 0, 255]

    dst_block9_ksize19_k6_1e_5 = cv2.cornerHarris(gray, 9, 19, 0.06)
    img6 = np.copy(img)
    img6[dst_block9_ksize19_k6_1e_5 > 0.00001 * dst_block9_ksize19_k6_1e_5.max()] = [0, 0, 255]

    titles = ["Original", "block9_ksize19", "dst_block5_ksize19", "dst_block9_ksize5", "dst_block9_ksize31",
              "dst_block9_ksize19_k6", "dst_block9_ksize19_k6_1e_5"]
    imgs = [img, img1, img2, img3, img4, img5, img6]
    for i in range(len(titles)):
        plt.subplot(3, 3, i + 1), plt.imshow(imgs[i]), plt.title(titles[i])
        plt.xticks([]), plt.yticks([])
    plt.show()
    # cv2.imshow('src',img)
    # cv2.imshow('dst',img5)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()

2.3 シフト

(1) SIFTアルゴリズム

  • SIFT (スケール不変特徴変換アルゴリズム) は、画像処理の分野で使用されるアルゴリズムです。SIFT はスケール不変性を持ち、画像内のキーポイントを検出でき、局所特徴記述子です。
  • そのアプリケーションには、オブジェクト認識、ロボットのマップ認識とナビゲーション、インフルエンス スティッチング、3D モデル構築、ジェスチャー認識、インフルエンス トラッキング、およびモーション比較が含まれます。

(2) SIFT特性

  • 独自性: つまり、特徴点は指紋のように分離でき、変動性が高く、大量のデータの要約や照合に適しています。
  • 豊富: 多くの機能が提供されています
  • 高速:速いです
  • 拡張可能: 他の特徴ベクトルと組み合わせて使用​​できます

(3) SIFTの特徴

  • 回転、スケーリング、平行移動の不変性
  • 画像のアフィン変換と射影変換のキーマッチングを解く
  • 光の影響が少ない
  • ターゲットのオクルージョンへの影響が少ない
  • 騒音や景観の影響が少ない

(4) SIFTアルゴリズムのステップ

  • スケール空間の極値検出 点検出
  • キーポイントの位置決め: いくつかの悪い特徴点を削除し、保存された特徴点は安定性やその他の条件を満たすことができます。
  • キー ポイントの方向パラメータ: キー ポイントが位置するスケール空間の近傍を取得し、領域の勾配と方向を計算し、計算結果に従って方向ヒストグラムを作成します。ヒストグラムのピークが主な方向パラメータです。
  • キー ポイント記述子: 各キー ポイントは、照明や視野角などの影響によって変化しないように、一連のベクトル (位置、スケール、方向) を使用してこのキー ポイントを記述します。
  • キーポイントマッチング: テンプレートグラフとリアルタイムグラフのそれぞれにキーポイント記述子セットを確立し、キーポイント記述子を比較することによって2つのキーポイントが同じかどうかを判断します。
#=================================SIFT===============================#
# flag = 0
flag = 1
if flag == 1:
    img = cv2.imread('harris2.png')
    gray= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    sift = cv2.xfeatures2d.SIFT_create()
    kp = sift.detect(gray,None)#找到关键点
    img=cv2.drawKeypoints(gray,kp,img)#绘制关键点
    cv2.imshow('sp',img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

3. 質感の特徴

(1) LBPの概要

  • LBP (ローカル バイナリ パターン) は、画像のローカル テクスチャ特性を記述するために使用される演算子であり、回転不変性やグレースケール不変性などの大きな利点があります。

(2) LBPの原理

  • LBP 演算子は 3×3 ウィンドウ内で定義され、ウィンドウの中心ピクセルを閾値として、隣接する 8 ピクセルのグレー値と比較し、周囲のピクセル値が中心ピクセル値より大きい場合、その位置は1 としてマークされ、それ以外の場合は 0 としてマークされます。これにより、8ビットの2進数(通常は10進数に変換、つまりLBPコード、計256種類)が得られ、この値がウィンドウ中央のピクセルのLBP値として使用されます。この3×3の領域情報のテクスチャを反映させます。

  •  数式:
  •  このうち、p は 3×3 ウィンドウ内の中心ピクセルを除いた p 番目のピクセルを表します。
  • l(c) は中心ピクセルのグレー値を表し、l(p) は近傍の p 番目のピクセルのグレー値を表します
  • s(x) の式は次のとおりです。
  •  LBP は中心ピクセルと隣接ピクセルの差を記録します
  • 照明の変化によりピクセルのグレー値が同時に増加および減少する場合、LBP の変化は明らかではありません。
  • LBP は照明の変化に敏感ではなく、LBP が検出するのは画像のテクスチャ情報のみです
#=================================LBP===============================#
# flag = 0
flag = 1
if flag == 1:
    def LBP(src):
        '''
        :param src:灰度图像
        :return:
        '''
        height = src.shape[0]
        width = src.shape[1]
        dst = src.copy()
        lbp_value = np.zeros((1, 8), dtype=np.uint8)
        # print(lbp_value)
        neighbours = np.zeros((1, 8), dtype=np.uint8)
        # print(neighbours)
        for x in range(1, width - 1):
            for y in range(1, height - 1):
                neighbours[0, 0] = src[y - 1, x - 1]
                neighbours[0, 1] = src[y - 1, x]
                neighbours[0, 2] = src[y - 1, x + 1]
                neighbours[0, 3] = src[y, x - 1]
                neighbours[0, 4] = src[y, x + 1]
                neighbours[0, 5] = src[y + 1, x - 1]
                neighbours[0, 6] = src[y + 1, x]
                neighbours[0, 7] = src[y + 1, x + 1]
                center = src[y, x]
                for i in range(8):
                    if neighbours[0, i] > center:
                        lbp_value[0, i] = 1
                    else:
                        lbp_value[0, i] = 0

                lbp = lbp_value[0, 0] * 1 + lbp_value[0, 1] * 2 + lbp_value[0, 2] * 4 + lbp_value[0, 3] * 8 \
                      + lbp_value[0, 4] * 16 + lbp_value[0, 5] * 32 + lbp_value[0, 6] * 64 + lbp_value[0, 7] * 128

                # print(lbp)
                dst[y, x] = lbp

        return dst

    img = cv2.imread('people.jpg', 0)
    print(img.shape)
    cv2.imshow('src', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    new_img = LBP(img)

    cv2.imshow('dst', new_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

 

4. テンプレートマッチング

(1) テンプレートマッチングの導入

  • テンプレート マッチングは、特定の対象の画像が画像内のどこに位置するかを調べて、画像の位置を特定する、最も原始的かつ基本的なパターン認識方法です。
  • 検出対象画像上で、テンプレート画像と重複サブ画像の一致度を左から右、上から下の順に計算し、一致度が大きいほど両者が同一である可能性が高くなります。

 (2) 関数: result = cv2.matchTemplate(画像, テンプレート, メソッド)

  • imageパラメータは検索する画像を示します
  • templ パラメータはテンプレート イメージを表します。テンプレート イメージは元のイメージより大きくなく、同じデータ型を持つ必要があります。
  • Methodパラメータは一致度の計算方法を示します。

(3) マッチング方法

  • TM_SQDIFF_NORMED は、2 つの画像間の二乗差を計算することによって照合される標準二乗差マッチングです。最もよく一致するものは 0 であり、一致が悪いほど一致値は大きくなります。
  • TM_CCORR_NORMED は、テンプレートと画像の乗算演算を使用する標準的な相関マッチングです。数値が大きいほど一致度が高く、0 は最もマッチング効果が低いことを意味します。この方法は、明るさの線形変化による類似度への影響を排除します。計算。
  • TM_CCOEFF_NORMED は標準的な相関係数マッチングであり、2 つのグラフからそれぞれの平均値を減算するだけでなく、それぞれの分散で除算する必要があります。テンプレートをその平均値とその平均値との相関関係と比較して照合します。完全一致の場合は 1、悪い一致の場合は -1、相関がまったくない場合は 0 (ランダム シーケンス)。

関数: minVal、maxVal、minLoc、maxLoc = cv2.minMaxLoc()

  • minVal パラメータは返される最小値を示します
  • maxVal パラメータは返される最大値を示します
  • minLoc パラメータは返される最小位置を示します
  • maxLoc パラメータは、返される最大位置を示します。
# =================================模板检测===============================#
# flag = 0
flag = 1
if flag == 1:

    def template_demo(tpl, target):

        methods = [cv2.TM_SQDIFF_NORMED, cv2.TM_CCORR_NORMED, cv2.TM_CCOEFF_NORMED]  # 3种模板匹配方法
        th, tw = tpl.shape[:2]
        for md in methods:
            # print(md)
            result = cv2.matchTemplate(target, tpl, md)
            # print(result.shape)
            min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
            print(min_val, max_val, min_loc, max_loc)
            if md == cv2.TM_SQDIFF_NORMED:
                tl = min_loc
            else:
                tl = max_loc
            br = (tl[0] + tw, tl[1] + th)  # br是矩形右下角的点的坐标
            cv2.rectangle(target, tl, br, (0, 0, 255), 2)
            cv2.namedWindow("match-" + np.str(md), cv2.WINDOW_NORMAL)
            cv2.imshow("match-" + np.str(md), target)


    tpl = cv2.imread("sample2.jpg")
    print(tpl.shape)
    target = cv2.imread("target1.jpg")
    print(target.shape)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    cv2.namedWindow('template image', cv2.WINDOW_NORMAL)
    cv2.imshow("template image", tpl)
    cv2.namedWindow('target image', cv2.WINDOW_NORMAL)
    cv2.imshow("target image", target)
    template_demo(tpl, target)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

5. 顔検出

  • 一般に、完全な顔認識システムは、顔検出、顔位置合わせ、人間の特徴抽出、顔認識という 4 つの主要コンポーネントで構成されます。
  • 4 つの部分からなるパイプライン操作:
    • 顔検出は画像内の顔の位置を検出します
    • 顔登録により、顔上のメガネ、鼻、口、その他の顔器官の位置が検出されます。
    • 顔特徴抽出により顔画像情報を文字列情報に抽象化
    • 顔認識では、対象の顔画像と既存の顔とを比較して類似度を計算し、対応する顔の同一性を確認します。

 

# =================================人脸检测===============================#
# flag = 0
flag = 1
if flag == 1:
    # 读入图像
    img = cv2.imread("3.png")

    # 加载人脸特征,该文件在 python安装目录\Lib\site-packages\cv2\data 下
    face_cascade = cv2.CascadeClassifier(r'haarcascade_frontalface_default.xml')
    # 将读取的图像转为COLOR_BGR2GRAY,减少计算强度
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 检测出的人脸个数
    faces = face_cascade.detectMultiScale(gray, scaleFactor=1.15, minNeighbors=4, minSize=(5, 5))

    print("Face : {0}".format(len(faces)))
    print(faces)
    # 用矩形圈出人脸的位置
    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)

    cv2.namedWindow("Faces")
    cv2.imshow("Faces", img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

# ==================================人脸检测===============================#
flag = 0
# flag = 1
if flag == 1:
    predictor_model = 'shape_predictor_68_face_landmarks/shape_predictor_68_face_landmarks.dat'
    detector = dlib.get_frontal_face_detector()
    predictor = dlib.shape_predictor(predictor_model)

    # cv2读取图像
    test_film_path = "3.png"
    img = cv2.imread(test_film_path)
    # 取灰度
    img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

    # 人脸数rects
    rects = detector(img_gray, 0)
    print(rects[0])
    for i in range(len(rects)):
        landmarks = np.matrix([[p.x, p.y] for p in predictor(img, rects[i]).parts()])
        print(landmarks, type(landmarks))
        for idx, point in enumerate(landmarks):
            # 68点的坐标
            pos = (point[0, 0], point[0, 1])
            # print(idx+1, pos)

            # 利用cv2.circle给每个特征点画一个圈,共68个
            cv2.circle(img, pos, 3, color=(0, 255, 0))
            # 利用cv2.putText输出1-68
            font = cv2.FONT_HERSHEY_SIMPLEX
            cv2.putText(img, str(idx + 1), pos, font, 0.5, (0, 0, 25 5), 1, cv2.LINE_AA)

    # cv2.imwrite("result.png", img)
    cv2.imshow("img", img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

履歴書コードデータセットを開く
カードをクリックして公式アカウントをフォロー [お姉さんがあなたをAIに連れて行ってくれます]
「履歴書を開く」と返信して受け取ります

おすすめ

転載: blog.csdn.net/m0_45447650/article/details/124408553