opencv python 输入键盘旋转任意角度图像

本文介绍了一个使用Python和OpenCV库实现的图像旋转和保存的脚本。脚本通过键盘输入控制图像的旋转角度,直到找到满意的旋转效果后进行保存。此过程在一个无限循环中进行,直至用户决定停止。
while(读取一个字符)
        读取图像
        if 字符 = r
            旋转一个角度
        else if 字符 = s
            保存图像
        else if 字符 = q
            break;    
from pynput import keyboard

import cv2
import numpy as np
import re

import cv2 as cv
import numpy as np
import os
#读取所有图像 ,重命名为VOC格式,选取部分图像进行平移变换

import os.path
import glob



def rotateImg(img,angel):
    rows, cols = img.shape
    M = cv2.getRotationMatrix2D(((cols - 1) / 2.0, (rows - 1) / 2.0), angel, 1)  # 旋转中心x,旋转中心y,旋转角度,缩放因子
    img = cv2.warpAffine(img, M, (cols, rows))  #在内存里完成了旋转
    cv2.namedWindow("旋转图像")
    cv2.imshow('旋转图像', img)
    cv2.waitKey(1000)
    cv2.destroyWindow("旋转图像")




if __name__ == '__main__':

    SourceImgPath = "C:\\darknet-master\\VOCdevkit\\VOC2007\\JPEGImages" + '\\'  # 文件路径
    total_sou = os.listdir(SourceImgPath)  # 获得所有图片名字
    #旋转图像
    for img_source in total_sou:
        ImgPath = os.path.join('%s%s' % (SourceImgPath, img_source))  # 获得文件夹下所有文件的路径   读取路径和保存路径
        img1 = cv2.imread(ImgPath, 0)  #读取图像

        # cols-1 and rows-1 are the coordinate limits.
        rotate_angel = 5

        while 1:
            line = input()
            print(line[0:1])
            if (line[0:1] == 'r'):  # 寻找到合适的旋转角度
                cv2.destroyAllWindows()  # 关闭之前的窗口
                rotateImg(img1, rotate_angel)#传参是非引用
                rotate_angel += 30
            elif (line[0:1] == 's'):
                #先旋转
                rows, cols = img1.shape
                M = cv2.getRotationMatrix2D(((cols - 1) / 2.0, (rows - 1) / 2.0), rotate_angel, 1)  # 旋转中心x,旋转中心y,旋转角度,缩放因子
                img1 = cv2.warpAffine(img1, M, (cols, rows))  # 在内存里完成了旋转
                #再保存
                cv.imwrite(ImgPath, img1)
            elif (line[0:1] == 'q'):
                break  # 下一张图像

<think>我们正在处理一个关于使用OpenCV实现低延迟任意角度视频旋转的问题。根据引用内容,我们知道OpenCV提供了视频读取和写入的类,以及图像预处理(包括旋转)的方法。但是,用户要求的是低延迟的任意角度视频旋转,这需要在视频流处理中高效地应用旋转变换。 关点: 1. 视频旋转通常涉及对每一帧应用旋转变换。 2. 任意角度旋转可以使用仿射变换(如旋转矩阵)或透视变换(但透视变换通常用于更复杂的变换,而旋转通常用仿射变换即可)。 3. 低延迟要求处理每一帧的时间尽可能短,避免帧堆积。 解决方案思路: 1. 使用cv2.VideoCapture捕获视频流(来自摄像头或视频文件)。 2. 对于每一帧,应用旋转变换。旋转中心通常设为图像中心,旋转角度由用户指定。 3. 使用cv2.warpAffine进行旋转,因为旋转是仿射变换的一种。 4. 为了减少延迟,需要优化旋转操作,例如使用硬件加速(如OpenCL)或减少不必要的计算。 5. 显示旋转后的帧或使用cv2.VideoWriter写入文件(如果不需要实时显示,写入文件可能会增加延迟,所以实时显示更注重低延迟)。 注意:任意角度旋转可能会引入黑边,因为旋转后的图像尺寸会变化。我们可以选择保持原始尺寸(裁剪)或调整输出尺寸以适应旋转后的图像(可能需要缩放)。 步骤: 1. 初始化视频捕获对象。 2. 循环读取每一帧。 3. 对每一帧应用旋转变换。 4. 显示旋转后的帧。 5. 释放资源。 旋转矩阵的构建: 使用cv2.getRotationMatrix2D(center, angle, scale)函数,其中: center: 旋转中心,通常为图像中心 (width/2, height/2) angle: 旋转角度(度),正数表示逆时针 scale: 缩放因子,1.0表示保持原大小 然后使用cv2.warpAffine(src, M, (width, height))进行变换。 为了低延迟,我们可以: - 使用多线程:将视频捕获和旋转处理放在不同线程,以减少等待时间。 - 使用GPU:如果OpenCV编译时支持OpenCL,则可以使用UMat(透明传输到GPU)来加速。 - 优化图像尺寸:如果原始分辨率很高,可以适当缩小图像以减少计算量。 - 避免不必要的内存分配:在循环外预先分配好输出图像的内存。 但是,由于OpenCVPython接口中,我们通常无法直接控制内存分配,但可以尝试使用UMat。 示例代码(使用UMat): import cv2 cap = cv2.VideoCapture(0) # 打开摄像头 while True: ret, frame = cap.read() if not ret: break # 将frame转换为UMat以使用GPU(如果可用) frame_umat = cv2.UMat(frame) height, width = frame.shape[:2] center = (width//2, height//2) # 假设旋转角度为30度 angle = 30 M = cv2.getRotationMatrix2D(center, angle, 1.0) # 使用warpAffine,注意输出尺寸设为原始尺寸(会裁剪) rotated_umat = cv2.warpAffine(frame_umat, M, (width, height)) rotated = cv2.UMat.get(rotated_umat) # 如果不需要在GPU上显示,可以转回Mat # 或者直接使用UMat进行显示 cv2.imshow('Rotated', rotated_umat) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() 注意:使用UMat并不一定总是更快,取决于你的OpenCV是否支持OpenCL以及硬件配置。如果硬件不支持,则回退到CPU。 另一种减少延迟的方法:使用多线程 我们可以将视频捕获放在一个线程,旋转和显示放在另一个线程,通过队列传递帧。 但是,由于用户要求任意角度,我们可能需要实时改变旋转角度。因此,可以在主循环中根据用户输入(如键盘)改变角度。 示例:允许用户按左/右改变旋转角度。 代码结构: angle = 0 while True: ... 读取帧 key = cv2.waitKey(1) if key == ord('a'): angle = (angle + 5) % 360 elif key == ord('d'): angle = (angle - 5) % 360 ... 然后旋转当前角度 这样用户就可以实时调整旋转角度。 关于旋转后的黑边问题:如果希望去除黑边,可以考虑在旋转后裁剪到内接矩形,但这会损失部分图像区域。或者,我们可以调整输出图像的大小以包含整个旋转后的图像,但这可能会改变分辨率。 总结:低延迟的关在于优化每一帧的处理时间,使用硬件加速和多线程是常用的方法。 根据引用[4],我们看到了透视变换的例子,但旋转通常用仿射变换即可,因为旋转是仿射变换的特例。透视变换用于更一般的平面变换,计算量更大,所以这里不采用。 因此,我们采用仿射变换(warpAffine)进行旋转。 下面我们给出一个完整的示例代码,包括: - 从摄像头捕获视频 - 实时旋转(通过仿射变换) - 允许键盘调整旋转角度 - 使用UMat(如果支持)以加速 注意:由于在部分环境中UMat可能不稳定,我们同时提供使用Mat的版本,并可以根据需要切换。 代码示例:</think>### OpenCV实现低延迟任意角度视频旋转的方法 要实现低延迟的任意角度视频旋转,需要结合高效的视频处理流程和优化的旋转算法。以下是关实现步骤和代码示例: #### 1. 核心方法:使用仿射变换旋转 ```python import cv2 import numpy as np # 初始化视频捕获 cap = cv2.VideoCapture(0) # 0表示默认摄像头 while True: ret, frame = cap.read() if not ret: break # 获取图像中心点和旋转角度(示例用30°) (h, w) = frame.shape[:2] center = (w // 2, h // 2) angle = 30 # 任意角度值 # 计算旋转矩阵并执行仿射变换 M = cv2.getRotationMatrix2D(center, angle, 1.0) rotated = cv2.warpAffine(frame, M, (w, h)) cv2.imshow("Rotated Video", rotated) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() ``` #### 2. 低延迟优化策略 1. **硬件加速配置** ```python # 启用OpenCL加速 cv2.ocl.setUseOpenCL(True) # 设置视频捕获参数 cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M','J','P','G')) # 使用MJPEG编码 cap.set(cv2.CAP_PROP_FPS, 60) # 提高帧率 ``` 2. **并行处理优化** ```python # 使用UMat实现GPU加速 frame_umat = cv2.UMat(frame) M = cv2.getRotationMatrix2D(center, angle, 1.0) rotated_umat = cv2.warpAffine(frame_umat, M, (w, h)) rotated = rotated_umat.get() ``` 3. **分辨率优化** ```python # 降低处理分辨率 scale_factor = 0.7 small_frame = cv2.resize(frame, None, fx=scale_factor, fy=scale_factor) # 旋转后恢复分辨率 rotated_hr = cv2.resize(rotated_small, (w, h)) ``` #### 3. 高级旋转技术(任意角度无黑边) ```python # 计算旋转后包含完整图像的新边界 def rotate_bound(image, angle): (h, w) = image.shape[:2] radians = np.deg2rad(angle) nw = int((abs(np.sin(radians)*h) + abs(np.cos(radians)*w)) nh = int((abs(np.cos(radians)*h) + abs(np.sin(radians)*w)) # 调整旋转中心 M = cv2.getRotationMatrix2D((w/2, h/2), angle, 1.0) M[0, 2] += (nw - w) / 2 M[1, 2] += (nh - h) / 2 return cv2.warpAffine(image, M, (nw, nh)) ``` #### 4. 实时角度控制 通过键盘输入动态调整旋转角度: ```python angle = 0 while True: # ...视频捕获代码... key = cv2.waitKey(1) if key == ord('a'): angle = (angle + 5) % 360 # 逆时针旋转 elif key == ord('d'): angle = (angle - 5) % 360 # 顺时针旋转 # ...旋转处理代码... ``` ### 性能优化建议 1. **硬件选择**:使用支持硬件编码的摄像头(如MJPG格式) 2. **内存优化**:预分配内存缓冲区 ```python rotated = np.zeros_like(frame) # 预分配内存 cv2.warpAffine(frame, M, (w, h), dst=rotated) # 重用内存 ``` 3. **多线程处理**:分离视频捕获和旋转处理线程 4. **编解码优化**:使用`cv2.VideoWriter_fourcc('X','V','I','D')`等高效编码[^3] > **关点**:旋转矩阵计算$M = \begin{bmatrix} \cos\theta & -\sin\theta & t_x \\ \sin\theta & \cos\theta & t_y \end{bmatrix}$的仿射变换是效率核心,其中$\theta$为旋转角度,$t_x, t_y$为平移量。通过GPU加速可将计算时间降至1-3ms/帧[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值