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)

上个效果图:

posted @ 2023-03-09 13:48  龙雪  阅读(7)  评论(0编辑  收藏  举报  来源