Python:Opencv 对图像/视频流的主要物体进行几何形状(如矩形、椭圆)拟合,并输出主要参数和拟合后的图像/视频
正经一句:拟合图像轮廓是指将边缘信息连接起来形成一个整体。通过对图像轮廓进行操作,可以获取目标图像的大小、位置和方向等信息。
不多废话,直接上代码,使用说明在注释基本解释清楚,其他的靠自己英语,可以评论留言但我可能很久才会回复....
"""
# @author : 龙雪
# @date : 2021-2-28 20:30:00
# @brief : geometry fitting
"""
import cv2 as cv # opencv版本为3.4.3.18 再高可能不兼容
import numpy as np
import pandas as pd
# image_path = "" # 图像路径
# im = cv.imread(image_path) # 若选择处理图像,吧下面和视频有关的语句以及for循环给去掉
video_path = "" # 视频路径
video_output_path = "" # 输出拟合视频的路径
csv_path = "xxxx.csv" # 输出参数文件路径
cap = cv.VideoCapture(video_path)
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
rate = cap.get(5)
n_frames = int(cap.get(7))
data_param = []
fourcc = cv.VideoWriter_fourcc(*'XVID')
out_video = cv.VideoWriter(video_output_path, fourcc, rate, (frame_width, frame_height))
for i in range(n_frames):
ret, frame = cap.read()
if np.max(frame) is None:
break
imgray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
_, binary = cv.threshold(imgray, 130, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)
image, contours, hierarchy = cv.findContours(binary, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
maxnum = 0
maxi = 0
frame_param = []
for i in range(len(contours)):
num = contours[i].shape[0]
if maxnum < num:
maxnum = num
maxi = i
retval = cv.fitEllipse(contours[maxi]) # 根据形状需要切换注释
# retval = cv.minAreaRect(contours[maxi])
for i in range(len(retval)):
if i == len(retval)-1:
frame_param.append(retval[i])
else:
frame_param.append(retval[i][0])
frame_param.append(retval[i][1])
data_param.append(frame_param)
img = cv.ellipse(frame, retval, (0, 0, 255), thickness=2) # 根据形状需要切换注释
# points = cv.boxPoints(retval)
# points = np.int0(points)
# img = cv.drawContours(frame, [points], 0, (0, 0, 255), 2)
out_video.write(img)
cv.imshow("geometry fitting", img)
cv.waitKey(int(1000/n_frames))
cap.release()
out_video.release()
cv.destroyAllWindows()
column = ['center point x', 'center point y', 'minor axis', 'long axis', 'angle']
record = pd.DataFrame(columns=column, data=data_param)
record.to_csv(csv_path)
上个效果图: