4
社区成员
发帖
与我相关
我的任务
分享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()