Bootstrap

Excel为数据绘制拆线图,并将均值线叠加在图上,以及整个过程的区域录屏python脚本

Excel为数据绘制拆线图,并将均值线叠加在图上,以及整个过程的区域录屏python脚本


Excel中有一组数据,希望画出曲线,并且能把均值线也绘制在图上,以下动画演示了整个过程,并且提供了区域录屏脚本,原理如下:
为节约空间,避免剪辑,只记录有效区域【仅记录鼠标区域且图像变化的图片】

1.演示动画

A.视频

Excel为数据绘制拆线图,并将均值线叠加在图上

B.gif动画

请添加图片描述

2.跟踪鼠标区域的录屏脚本

import cv2
import numpy as np
import mss
import time
import threading
import pyautogui
import datetime
from skimage.metrics import structural_similarity as ssim
from pynput import mouse

def compute_ssim(imageA, imageB):
    """计算两幅图像的结构相似性指数(SSIM)"""
    grayA = cv2.cvtColor(imageA, cv2.COLOR_BGR2GRAY)
    grayB = cv2.cvtColor(imageB, cv2.COLOR_BGR2GRAY)
    (score, diff) = ssim(grayA, grayB, full=True)
    return score

def resize_and_pad(image, size=(640, 640)):
    """等比缩放并填充图像"""
    h, w = image.shape[:2]
    scale = min(size[0] / w, size[1] / h)
    new_w, new_h = int(w * scale), int(h * scale)
    
    resized_image = cv2.resize(image, (new_w, new_h))
    
    # 创建黑色背景
    top = (size[1] - new_h) // 2
    bottom = size[1] - new_h - top
    left = (size[0] - new_w) // 2
    right = size[0] - new_w - left
    
    padded_image = cv2.copyMakeBorder(resized_image, top, bottom, left, right, cv2.BORDER_CONSTANT, value=[0, 0, 0])
    return padded_image

is_mouse_pressed=False
def on_click(x, y, button, pressed):
    global is_mouse_pressed
    is_mouse_pressed = pressed

def capture_screen(stop_event):
    layout_w=720
    layout_h=1280
    
    mouse_listener = mouse.Listener(on_click=on_click)
    mouse_listener.start()
    with mss.mss() as sct:
        # 初始化第一帧
        monitor = sct.monitors[1]
        print(monitor)
        frame1 = None
        screen_width = monitor["width"]
        screen_height = monitor["height"]
        
        fourcc = cv2.VideoWriter_fourcc(*'XVID')
        out = cv2.VideoWriter('output.avi', fourcc, 3.0, (layout_w, layout_h))
        
        area=None
        
        while not stop_event.is_set():
            mouse_x, mouse_y = pyautogui.position()    
            
            if area:
                if mouse_x<area['left'] or mouse_x>area['left']+layout_w or mouse_y<area['top'] or mouse_y>area['top']+layout_h:
                    area=None
            
            if area is None and is_mouse_pressed:                    
                # 计算截取区域,以鼠标为中心640x640,同时进行边界检查
                left = max(0, min(screen_width - layout_w, mouse_x - layout_w // 2))
                top = max(0, min(screen_height - layout_h, mouse_y - layout_h // 2))
                area = {'top': top, 'left': left, 'width': layout_w, 'height': layout_h}
                        
            if area:
                frame2 = np.array(sct.grab(area))
                frame2 = cv2.cvtColor(frame2, cv2.COLOR_BGRA2BGR)

                # 在 frame2 上绘制一个小圆点标记鼠标位置
                relative_mouse_x = mouse_x - area['left']
                relative_mouse_y = mouse_y - area['top']
                cv2.circle(frame2, (relative_mouse_x, relative_mouse_y), 5, (0, 0, 255), -1)  # 红色小圆点

                frame2=resize_and_pad(frame2,(layout_w,layout_h))
                if frame1 is None:
                    frame1 = frame2.copy()
                    continue
                    
                score = compute_ssim(frame1, frame2)
                if score<1.0:
                    out.write(frame2)

                frame1 = frame2.copy()
            
            # 适量的延时,防止过高的CPU使用率
            time.sleep(0.1)
        out.release()
        
if __name__ == '__main__':
    stop_event = threading.Event()

    # 启动屏幕捕捉的线程
    capture_thread = threading.Thread(target=capture_screen, args=(stop_event,))
    capture_thread.start()

    # 等待用户输入'q'以停止捕捉
    while True:
        if input().strip().lower() == 'q':
            stop_event.set()
            break

    # 等待屏幕捕捉线程结束
    capture_thread.join()
    print("捕获已结束并退出。")

    from moviepy.editor import VideoFileClip

    # 定义视频文件路径和输出GIF文件路径
    input_video_path = 'output.avi'
    output_gif_path = 'output.gif'

    # 加载视频文件
    clip = VideoFileClip(input_video_path)
    
    clip = clip.subclip(3, -2)
    clip = clip.resize(0.4)
    # 将视频剪辑转换为GIF
    clip.write_gif(output_gif_path, fps=2)
    print(f"GIF文件保存到 {output_gif_path}")
   
;