search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

fanfuhan OpenCV 教學078 ~ opencv-078-識別(尋找/標記)與跟踪(鎖定/定位)視頻中的特定顏色對象 – jashliao部落格

fanfuhan OpenCV 教學078 ~ opencv-078-識別(尋找/標記)與跟踪(鎖定/定位)視頻中的特定顏色對象

資料來源: https://fanfuhan.github.io/

https://fanfuhan.github.io/2019/04/24/opencv-078/

GITHUB:https://github.com/jash-git/fanfuhan_ML_OpenCV


圖像處理與二值分析的視頻版本,通過讀取視頻每一幀的圖像,然後對圖像二值分析,得到指定的色塊區域,主要步驟如下:

    色彩轉換BGR2HSV
    inRange提取顏色區域mask
    對mask區域進行二值分析得到位置與輪廓信息
    繪製外接橢圓與中心位置
    顯示結果

其中涉及到的知識點主要包括圖像處理、色彩空間轉換、形態學、輪廓分析等。


C++

#include 
#include 

using namespace std;
using namespace cv;

void process_frame(Mat &image);

/*
 * 识别与跟踪视频中的特定颜色对象
 */
int main() {
    VideoCapture capture("../images/color_object.mp4");
    if (!capture.isOpened()) {
        printf("could not open camera...\n");
        return -1;
    }

    int fps = capture.get(CAP_PROP_FPS);
    int width = capture.get(CAP_PROP_FRAME_WIDTH);
    int height = capture.get(CAP_PROP_FRAME_HEIGHT);
    int num_of_frames = capture.get(CAP_PROP_FRAME_COUNT);
    printf("frame width: %d, frame height: %d, FPS : %d \n", width, height, fps);

    Mat frame;
    while (true) {
        bool ret = capture.read(frame);
        if (!ret) break;
        imshow("input", frame);
        char c = waitKey(50);
        process_frame(frame);
        imshow("result", frame);
        if (c == 27) {
            break;
        }
    }
    waitKey(0);
    return 0;

    waitKey(0);
    return 0;
}

void process_frame(Mat &image) {
    Mat hsv, mask;
    // 转换色彩空间
    cvtColor(image, hsv, COLOR_BGR2HSV);

    // 提取颜色区域mask
    inRange(hsv, Scalar(0, 43, 46), Scalar(10, 255, 255), mask);
    Mat se = getStructuringElement(MORPH_RECT, Size(15, 15));
    morphologyEx(mask, mask, MORPH_OPEN, se);

    // 寻找最大轮廓
    vector> contours;
    vector hierarchy;
    findContours(mask, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
    int index = -1;
    int max = 0;
    for (size_t t = 0; t < contours.size(); t++) {
        double area = contourArea(contours[t]);
        if (area > max) {
            max = area;
            index = t;
        }
    }

    // 绘制外接轮廓
    if (index >= 0) {
        RotatedRect rect = minAreaRect(contours[index]);
        ellipse(image, rect, Scalar(0, 255, 0), 2);
        circle(image, rect.center, 2, Scalar(255, 0, 0), 2);
    }
}


Python

import cv2 as cv
import numpy as np

capture = cv.VideoCapture("D:/images/video/test.mp4")
height = capture.get(cv.CAP_PROP_FRAME_HEIGHT)
width = capture.get(cv.CAP_PROP_FRAME_WIDTH)
count = capture.get(cv.CAP_PROP_FRAME_COUNT)
fps = capture.get(cv.CAP_PROP_FPS)
print(height, width, count, fps)


def process(image, opt=1):
    hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)
    line = cv.getStructuringElement(cv.MORPH_RECT, (15, 15), (-1, -1))
    mask = cv.inRange(hsv, (0, 43, 46), (10, 255, 255))
    mask = cv.morphologyEx(mask, cv.MORPH_OPEN, line)

    # 轮廓提取, 发现最大轮廓
    out, contours, hierarchy = cv.findContours(mask, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    index = -1
    max = 0
    for c in range(len(contours)):
        area = cv.contourArea(contours[c])
        if area > max:
            max = area
            index = c
    # 绘制
    if index >= 0:
        rect = cv.minAreaRect(contours[index])
        cv.ellipse(image, rect, (0, 255, 0), 2, 8)
        cv.circle(image, (np.int32(rect[0][0]), np.int32(rect[0][1])), 2, (255, 0, 0), 2, 8, 0)
    return image


while(True):
    ret, frame = capture.read()
    if ret is True:
        cv.imshow("video-input", frame)
        result = process(frame)
        cv.imshow("result", result)
        c = cv.waitKey(50)
        print(c)
        if c == 27:  #ESC
            break
    else:
        break
cv.waitKey(0)
cv.destroyAllWindows()


熱門推薦

本文由 jashliaoeuwordpress 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦