OpenCV功能封装类-1

人工智能 2025-04-17 09:43:33

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt


class OpenCVFunctions:
    def __init__(self):
        pass

    def show_and_destroy_image(self, img, window_name='draw'):
        """
        显示图像并等待按键,最后销毁窗口。

        参数:
        img (np.ndarray): 要显示的图像。
        window_name (str): 窗口的名称,默认为 'draw'。
        """
        cv.imshow(window_name, img)
        cv.waitKey(0)
        cv.destroyAllWindows()

    def load_and_show_gray_image(self, image_path):
        """
        加载并显示灰度图像。

        参数:
        image_path (str): 图像文件的路径。

        引用实例:
        opencv = OpenCVFunctions()
        opencv.load_and_show_gray_image('66.png')
        """
        img = cv.imread(image_path, 0)
        if img is not None:
            self.show_and_destroy_image(img, 'pkq')
        else:
            print(f"无法加载图像: {image_path}")

    def load_gray_image_and_save(self, image_path, save_path):
        """
        加载灰度图像并保存。

        参数:
        image_path (str): 原始图像文件的路径。
        save_path (str): 保存图像的路径。

        引用实例:
        opencv = OpenCVFunctions()
        opencv.load_gray_image_and_save('66.png', 'pkq.png')
        """
        img = cv.imread(image_path, 0)
        if img is not None:
            cv.namedWindow('image', cv.WINDOW_NORMAL)
            cv.imshow('pkq', img)
            cv.imwrite(save_path, img)
            self.show_and_destroy_image(img, 'pkq')
        else:
            print(f"无法加载图像: {image_path}")

    def show_image_with_matplotlib(self, image_path):
        """
        使用matplotlib显示灰度图像。

        参数:
        image_path (str): 图像文件的路径。

        引用实例:
        opencv = OpenCVFunctions()
        opencv.show_image_with_matplotlib('66.png')
        """
        img = cv.imread(image_path, 0)
        if img is not None:
            plt.imshow(img, cmap='gray', interpolation='bicubic')
            plt.xticks([]), plt.yticks([])
            plt.show()
        else:
            print(f"无法加载图像: {image_path}")

    def read_video_from_camera(self):
        """
        从相机读取视频并显示灰度帧。

        引用实例:
        opencv = OpenCVFunctions()
        opencv.read_video_from_camera()
        """
        cap = cv.VideoCapture(0)
        if not cap.isOpened():
            print("无法打开相机")
            return
        while True:
            ret, frame = cap.read()
            if not ret:
                print("无法接收帧,退出...")
                break
            gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
            cv.imshow('frame', gray)
            if cv.waitKey(1) == ord('q'):
                break
        cap.release()
        cv.destroyAllWindows()

    def play_video_from_file(self, video_path):
        """
        从文件播放视频并显示灰度帧。

        参数:
        video_path (str): 视频文件的路径。

        引用实例:
        opencv = OpenCVFunctions()
        opencv.play_video_from_file('Record-rec20250411165905.mp4')
        """
        cap = cv.VideoCapture(video_path)
        while cap.isOpened():
            ret, frame = cap.read()
            if not ret:
                print("无法接收帧,退出...")
                break
            gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
            cv.imshow('frame', gray)
            if cv.waitKey(1) == ord('q'):
                break
        cap.release()
        cv.destroyAllWindows()

   

def save_video(self, input_video_path, output_video_path):
    """
    保存视频。

    参数:
    input_video_path (str): 输入视频文件的路径。
    output_video_path (str): 输出视频文件的路径。

    引用实例:
    opencv = OpenCVFunctions()
    opencv.save_video('Record-rec20250411165905.mp4', 'output.avi')
    """
    try:
        # 尝试打开输入视频文件
        cap = cv.VideoCapture(input_video_path)
        if not cap.isOpened():
            raise Exception(f"无法打开输入视频文件: {input_video_path}")

        # 获取输入视频的帧率和尺寸
        fps = cap.get(cv.CAP_PROP_FPS)
        width = int(cap.get(cv.CAP_PROP_FRAME_WIDTH))
        height = int(cap.get(cv.CAP_PROP_FRAME_HEIGHT))

        # 定义视频编码器
        fourcc = cv.VideoWriter_fourcc(*'XVID')
        # 创建视频写入对象,使用动态获取的帧率和尺寸
        out = cv.VideoWriter(output_video_path, fourcc, fps, (width, height))
        if not out.isOpened():
            raise Exception(f"无法创建输出视频文件: {output_video_path}")

        while cap.isOpened():
            ret, frame = cap.read()
            if not ret:
                print("无法接收帧,退出...")
                break

            # 垂直翻转帧
            frame = cv.flip(frame, 0)
            # 写入帧到输出视频文件
            out.write(frame)
            # 显示帧
            cv.imshow('frame', frame)

            # 检查是否按下 'q' 键
            if cv.waitKey(1) == ord('q'):
                break

    except Exception as e:
        print(f"保存视频时出现错误: {e}")
    finally:
        # 确保释放相机资源和视频写入对象,并关闭所有窗口
        if 'cap' in locals() and cap.isOpened():
            cap.release()
        if 'out' in locals() and out.isOpened():
            out.release()
        cv.destroyAllWindows()

    def draw_line(self, img, start_point, end_point, color=(255, 0, 0), thickness=5):
        """
        在图像上绘制一条线。

        参数:
        img (np.ndarray): 要绘制线条的图像。
        start_point (tuple): 线的起始点,格式为 (x1, y1)。
        end_point (tuple): 线的结束点,格式为 (x2, y2)。
        color (tuple): 线的颜色,格式为 (B, G, R),默认为蓝色 (255, 0, 0)。
        thickness (int): 线的厚度,默认为 5。

        引用实例:
        opencv = OpenCVFunctions()
        img = np.zeros((520, 520, 3), np.uint8)
        opencv.draw_line(img, (0, 0), (512, 512))
        opencv.show_and_destroy_image(img)
        """
        cv.line(img, start_point, end_point, color, thickness)
        return img

    def draw_rectangle(self, img, top_left, bottom_right, color=(0, 255, 0), thickness=3):
        """
        在图像上绘制一个矩形。

        参数:
        img (np.ndarray): 要绘制矩形的图像。
        top_left (tuple): 矩形的左上角点,格式为 (x1, y1)。
        bottom_right (tuple): 矩形的右下角点,格式为 (x2, y2)。
        color (tuple): 矩形的颜色,格式为 (B, G, R),默认为绿色 (0, 255, 0)。
        thickness (int): 矩形边框的厚度,默认为 3。

        引用实例:
        opencv = OpenCVFunctions()
        img = np.zeros((520, 520, 3), np.uint8)
        opencv.draw_rectangle(img, (275, 0), (510, 128))
        opencv.show_and_destroy_image(img)
        """
        cv.rectangle(img, top_left, bottom_right, color, thickness)
        return img

    def draw_circle(self, img, center, radius, color=(0, 0, 255), thickness=-1):
        """
        在图像上绘制一个圆圈。

        参数:
        img (np.ndarray): 要绘制圆圈的图像。
        center (tuple): 圆圈的中心点,格式为 (x, y)。
        radius (int): 圆圈的半径。
        color (tuple): 圆圈的颜色,格式为 (B, G, R),默认为红色 (0, 0, 255)。
        thickness (int): 圆圈边框的厚度,-1 表示填充,默认为 -1。

        引用实例:
        opencv = OpenCVFunctions()
        img = np.zeros((520, 520, 3), np.uint8)
        opencv.draw_circle(img, (280, 75), 70)
        opencv.show_and_destroy_image(img)
        """
        cv.circle(img, center, radius, color, thickness)
        return img

    def draw_ellipse(self, img, center, axes, angle=0, start_angle=0, end_angle=180, color=255, thickness=-1):
        """
        在图像上绘制一个椭圆。

        参数:
        img (np.ndarray): 要绘制椭圆的图像。
        center (tuple): 椭圆的中心点,格式为 (x, y)。
        axes (tuple): 椭圆的长轴和短轴长度,格式为 (长轴, 短轴)。
        angle (int): 椭圆的旋转角度,默认为 0。
        start_angle (int): 椭圆的起始角度,默认为 0。
        end_angle (int): 椭圆的结束角度,默认为 180。
        color (tuple or int): 椭圆的颜色,格式为 (B, G, R) 或单通道值,默认为 255。
        thickness (int): 椭圆边框的厚度,-1 表示填充,默认为 -1。

        引用实例:
        opencv = OpenCVFunctions()
        img = np.zeros((520, 520, 3), np.uint8)
        opencv.draw_ellipse(img, (361, 361), (100, 50))
        opencv.show_and_destroy_image(img)
        """
        cv.ellipse(img, center, axes, angle, start_angle, end_angle, color, thickness)
        return img

    def draw_polygon(self, img, points, is_closed=True, color=(0, 255, 255)):
        """
        在图像上绘制一个多边形。

        参数:
        img (np.ndarray): 要绘制多边形的图像。
        points (list): 多边形的顶点列表,每个顶点为 (x, y) 格式的元组。
        is_closed (bool): 多边形是否闭合,默认为 True。
        color (tuple): 多边形的颜色,格式为 (B, G, R),默认为黄色 (0, 255, 255)。

        引用实例:
        opencv = OpenCVFunctions()
        img = np.zeros((520, 520, 3), np.uint8)
        points = [[10, 5], [20, 25], [70, 100], [50, 85]]
        opencv.draw_polygon(img, points)
        opencv.show_and_destroy_image(img)
        """
        pts = np.array(points, np.int32)
        pts = pts.reshape((-1, 1, 2))
        cv.polylines(img, [pts], is_closed, color)
        return img

    def draw_text(self, img, text, org, font=cv.FONT_HERSHEY_SIMPLEX, font_scale=4, color=(255, 255, 255), thickness=2, line_type=cv.LINE_AA):
        """
        在图像上添加文本。

        参数:
        img (np.ndarray): 要添加文本的图像。
        text (str): 要添加的文本内容。
        org (tuple): 文本的起始位置,格式为 (x, y)。
        font (int): 字体类型,默认为 cv.FONT_HERSHEY_SIMPLEX。
        font_scale (float): 字体大小比例,默认为 4。
        color (tuple): 文本的颜色,格式为 (B, G, R),默认为白色 (255, 255, 255)。
        thickness (int): 文本的厚度,默认为 2。
        line_type (int): 线条类型,默认为 cv.LINE_AA。

        引用实例:
        opencv = OpenCVFunctions()
        img = np.zeros((520, 520, 3), np.uint8)
        opencv.draw_text(img, 'Candy', (10, 500))
        opencv.show_and_destroy_image(img)
        """
        cv.putText(img, text, org, font, font_scale, color, thickness, line_type)
        return img

    def draw_shapes_and_text(self):
        """
        在图像上绘制各种形状和文本。

        引用实例:
        opencv = OpenCVFunctions()
        opencv.draw_shapes_and_text()
        """
        img = np.zeros((520, 520, 3), np.uint8)
        img = self.draw_line(img, (0, 0), (512, 512))
        img = self.draw_rectangle(img, (275, 0), (510, 128))
        img = self.draw_circle(img, (280, 75), 70)
        img = self.draw_ellipse(img, (361, 361), (100, 50))
        points = [[10, 5], [20, 25], [70, 100], [50, 85]]
        img = self.draw_polygon(img, points)
        img = self.draw_text(img, 'Candy', (10, 500))
        self.show_and_destroy_image(img)

    def draw_circle_on_double_click(self):
        """
        双击鼠标左键在图像上绘制圆圈。

        引用实例:
        opencv = OpenCVFunctions()
        opencv.draw_circle_on_double_click()
        """
        def draw_circle(event, x, y, flags, param):
            if event == cv.EVENT_LBUTTONDBLCLK:
                cv.circle(img, (x, y), 100, (255, 0, 0), -1)

        img = np.zeros((512, 512, 3), np.uint8)
        cv.namedWindow('image')
        cv.setMouseCallback('image', draw_circle)
        while True:
            cv.imshow('image', img)
            if cv.waitKey(20) & 0xFF == 27:
                break
        cv.destroyAllWindows()

    def draw_shape_with_mouse(self):
        """
        使用鼠标绘制矩形或圆圈。

        引用实例:
        opencv = OpenCVFunctions()
        opencv.draw_shape_with_mouse()
        """
        drawing = False
        mode = True
        ix, iy = -1, -1

        def draw_circle(event, x, y, flags, param):
            nonlocal ix, iy, drawing, mode
            if event == cv.EVENT_LBUTTONDOWN:
                drawing = True
                ix, iy = x, y
            elif event == cv.EVENT_MOUSEMOVE:
                if drawing:
                    if mode:
                        cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)
                    else:
                        cv.circle(img, (x, y), 5, (0, 0, 255), -1)
            elif event == cv.EVENT_LBUTTONUP:
                drawing = False
                if mode:
                    cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)
                else:
                    cv.circle(img, (x, y), 5, (0, 0, 255), -1)

        img = np.zeros((512, 512, 3), np.uint8)
        cv.namedWindow('image')
        cv.setMouseCallback('image', draw_circle)
        while True:
            cv.imshow('image', img)
            if cv.waitKey(20) & 0xFF == 27:
                break
        cv.destroyAllWindows()

    def trackbar_as_color_palette(self):
        """
        使用轨迹栏作为调色板。

        引用实例:
        opencv = OpenCVFunctions()
        opencv.trackbar_as_color_palette()
        """
        def nothing(x):
            pass

        img = np.zeros((300, 512, 3), np.uint8)
        cv.namedWindow('image')
        cv.createTrackbar('R', 'image', 0, 255, nothing)
        cv.createTrackbar('G', 'image', 0, 255, nothing)
        cv.createTrackbar('B', 'image', 0, 255, nothing)
        switch = '0 : OFF \n1 : ON'
        cv.createTrackbar(switch, 'image', 0, 1, nothing)
        while True:
            cv.imshow('image', img)
            k = cv.waitKey(1) & 0xFF
            if k == 27:
                break
            r = cv.getTrackbarPos('R', 'image')
            g = cv.getTrackbarPos('G', 'image')
            b = cv.getTrackbarPos('B', 'image')
            s = cv.getTrackbarPos(switch, 'image')
            if s == 0:
                img[:] = 0
            else:
                img[:] = [b, g, r]
        cv.destroyAllWindows()
    

...全文
117 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

4

社区成员

发帖
与我相关
我的任务
社区描述
学习交流人工智能相关算法及技术栈
opencv计算机视觉人工智能 技术论坛(原bbs) 广东省·深圳市
社区管理员
  • 亿只小灿灿
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧