Zi 字媒體
2017-07-25T20:27:27+00:00
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()
寫了
5860316篇文章,獲得
23313次喜歡