OpenCV图像透视处理

举报
鱼弦 发表于 2024/09/18 09:14:19 2024/09/18
【摘要】 OpenCV图像透视处理 介绍图像透视变换是指将图像从一个视角转换到另一个视角的过程。它广泛应用于计算机视觉和图像处理领域,能够校正图像中的倾斜、扭曲,使其看起来更加规范。 应用使用场景文档扫描:校正拍摄时产生的角度偏差。增强现实(AR):将虚拟对象准确地投影到真实世界视角中。机器人导航:通过透视变换进行地图校正和路径规划。3D重建:从不同角度的图像生成三维模型。 文档扫描:校正拍摄时产生...

OpenCV图像透视处理

介绍

图像透视变换是指将图像从一个视角转换到另一个视角的过程。它广泛应用于计算机视觉和图像处理领域,能够校正图像中的倾斜、扭曲,使其看起来更加规范。

应用使用场景

  1. 文档扫描:校正拍摄时产生的角度偏差。
  2. 增强现实(AR):将虚拟对象准确地投影到真实世界视角中。
  3. 机器人导航:通过透视变换进行地图校正和路径规划。
  4. 3D重建:从不同角度的图像生成三维模型。

文档扫描:校正拍摄时产生的角度偏差

import cv2
import numpy as np

def correct_perspective(image_path):
    image = cv2.imread(image_path)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    thresh = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)[1]

    contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    largest_contour = max(contours, key=cv2.contourArea)

    rect = cv2.minAreaRect(largest_contour)
    box = cv2.boxPoints(rect)
    box = np.int0(box)

    width, height = int(rect[1][0]), int(rect[1][1])
    
    src_pts = box.astype("float32")
    dst_pts = np.array([[0, height-1], [0, 0], [width-1, 0], [width-1, height-1]], dtype="float32")

    M = cv2.getPerspectiveTransform(src_pts, dst_pts)
    warped = cv2.warpPerspective(image, M, (width, height))

    return warped

corrected_image = correct_perspective('scanned_document.jpg')
cv2.imwrite('corrected_document.jpg', corrected_image)

增强现实(AR):将虚拟对象准确地投影到真实世界视角中

import cv2
import numpy as np

def project_virtual_object(real_image_path, virtual_image_path, homography):
    real_image = cv2.imread(real_image_path)
    virtual_image = cv2.imread(virtual_image_path)

    h, w, _ = virtual_image.shape
    pts_virtual = np.float32([[0, 0], [0, h], [w, h], [w, 0]]).reshape(-1, 1, 2)

    pts_real = cv2.perspectiveTransform(pts_virtual, homography)
    
    mask = np.zeros((real_image.shape[0], real_image.shape[1]), dtype=np.uint8)
    cv2.fillPoly(mask, [np.int32(pts_real)], (255, 255, 255))

    virtual_transformed = cv2.warpPerspective(virtual_image, homography, (real_image.shape[1], real_image.shape[0]))

    combined = cv2.bitwise_and(real_image, real_image, mask=cv2.bitwise_not(mask))
    combined = cv2.add(combined, virtual_transformed)

    return combined

homography_matrix = np.array([[1.0, 0.0, 100.0], [0.0, 1.0, 50.0], [0.0, 0.0, 1.0]]) 
result = project_virtual_object('real_world.jpg', 'virtual_object.png', homography_matrix)
cv2.imwrite('augmented_reality.jpg', result)

机器人导航:通过透视变换进行地图校正和路径规划

import cv2
import numpy as np

def map_correction(map_image_path):
    map_image = cv2.imread(map_image_path)
    gray = cv2.cvtColor(map_image, cv2.COLOR_BGR2GRAY)
    thresh = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)[1]

    contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    largest_contour = max(contours, key=cv2.contourArea)

    rect = cv2.minAreaRect(largest_contour)
    box = cv2.boxPoints(rect)
    box = np.int0(box)

    width, height = int(rect[1][0]), int(rect[1][1])

    src_pts = box.astype("float32")
    dst_pts = np.array([[0, height-1], [0, 0], [width-1, 0], [width-1, height-1]], dtype="float32")

    M = cv2.getPerspectiveTransform(src_pts, dst_pts)
    corrected_map = cv2.warpPerspective(map_image, M, (width, height))

    return corrected_map, M

corrected_map, transformation_matrix = map_correction('robot_map.jpg')
cv2.imwrite('corrected_robot_map.jpg', corrected_map)

3D重建:从不同角度的图像生成三维模型

import cv2
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

def reconstruct_3D(img1_path, img2_path, calib_matrix):
    img1 = cv2.imread(img1_path, 0)
    img2 = cv2.imread(img2_path, 0)

    sift = cv2.SIFT_create()
    kp1, des1 = sift.detectAndCompute(img1, None)
    kp2, des2 = sift.detectAndCompute(img2, None)

    bf = cv2.BFMatcher(cv2.NORM_L2, crossCheck=True)
    matches = bf.match(des1, des2)
    matches = sorted(matches, key=lambda x: x.distance)
    
    pts1 = np.float32([kp1[m.queryIdx].pt for m in matches]).reshape(-1, 1, 2)
    pts2 = np.float32([kp2[m.trainIdx].pt for m in matches]).reshape(-1, 1, 2)

    E, mask = cv2.findEssentialMat(pts1, pts2, calib_matrix)
    _, R, t, mask = cv2.recoverPose(E, pts1, pts2, calib_matrix)

    pts1 = pts1[mask.ravel() == 1]
    pts2 = pts2[mask.ravel() == 1]

    P1 = np.hstack((np.eye(3), np.zeros((3, 1))))
    P2 = np.hstack((R, t))

    pts1_hom = cv2.convertPointsToHomogeneous(pts1)[:, 0, :]
    pts2_hom = cv2.convertPointsToHomogeneous(pts2)[:, 0, :]

    points_4d = cv2.triangulatePoints(P1, P2, pts1_hom.T[:2], pts2_hom.T[:2])
    points_3d = points_4d / points_4d[3]
    points_3d = points_3d[:3].T

    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.scatter(points_3d[:, 0], points_3d[:, 1], points_3d[:, 2])
    plt.show()

calib_matrix = np.array([[718.856, 0, 607.1928], [0, 718.856, 185.2157], [0, 0, 1]])
reconstruct_3D('image1.jpg', 'image2.jpg', calib_matrix)

原理解释

透视变换是一种二维到二维的线性变换,通过四个对应点确定出一个仿射矩阵,将源图像映射到目标图像上。

算法原理流程图

1. 输入四对对应点
   └──> 2. 构建透视变换矩阵
         └──> 3. 使用透视变换矩阵进行图像变换
               └──> 4. 输出结果图像

算法原理解释

  1. 输入四对对应点
    • 获取原图像中的四个顶点,以及对应目标图像中的四个顶点。
  2. 构建透视变换矩阵
    • 使用OpenCV函数cv2.getPerspectiveTransform来计算3x3的透视变换矩阵。
  3. 使用透视变换矩阵进行图像变换
    • 利用cv2.warpPerspective函数进行图像映射。
  4. 输出结果图像
    • 得到透视变换后的新图像。

实际详细应用TDengine代码示例实现

假设我们需要在TDengine数据库中记录每次图像透视变换的时间戳和相关参数。

安装和设置

# 下载并安装TDengine
wget https://www.taosdata.com/download/latest/
tar xzvf TDengine-*.tar.gz
cd TDengine-*/
sudo ./install.sh

创建数据库和表

CREATE DATABASE image_processing;
USE image_processing;
CREATE TABLE perspective_transform(ts TIMESTAMP, src_points BINARY(100), dst_points BINARY(100), matrix BINARY(100));

Python代码示例

import cv2
import numpy as np
import taos
from datetime import datetime

# 连接TDengine
conn = taos.connect('localhost', 'root', 'taosdata', 'image_processing')

def perspective_transform(image_path, src_pts, dst_pts):
    # 读取输入图像
    img = cv2.imread(image_path)
    rows, cols, ch = img.shape
    
    # 计算透视变换矩阵
    M = cv2.getPerspectiveTransform(src_pts, dst_pts)
    
    # 进行透视变换
    dst = cv2.warpPerspective(img, M, (cols, rows))
    
    # 转换矩阵及点集为字符串用于存储
    src_points_str = str(src_pts.tolist())
    dst_points_str = str(dst_pts.tolist())
    matrix_str = str(M.tolist())
    
    # 插入数据到数据库
    cursor = conn.cursor()
    cursor.execute(f"INSERT INTO perspective_transform VALUES ('{datetime.now()}', '{src_points_str}', '{dst_points_str}', '{matrix_str}')")
    cursor.close()
    
    return dst

# 示例输入输出点
src_points = np.float32([[10, 10], [200, 50], [50, 200], [220, 220]])
dst_points = np.float32([[0, 0], [300, 0], [0, 300], [300, 300]])

# 调用函数
output_image = perspective_transform("input.jpg", src_points, dst_points)

# 保存结果图像
cv2.imwrite("output.jpg", output_image)

测试代码

确保已创建了合适的测试图片input.jpg

# 加载并显示原始与变换后的图像
import matplotlib.pyplot as plt

original_img = cv2.imread("input.jpg")
transformed_img = cv2.imread("output.jpg")

plt.subplot(121),plt.imshow(cv2.cvtColor(original_img, cv2.COLOR_BGR2RGB)),plt.title('Original Image')
plt.subplot(122),plt.imshow(cv2.cvtColor(transformed_img, cv2.COLOR_BGR2RGB)),plt.title('Transformed Image')
plt.show()

部署场景

在部署环境中,可以使用定期任务(例如cron jobs)自动对指定目录中的新图像进行透视变换,并将结果和元数据存储到TDengine数据库中。

配置Cron Job

编辑crontab文件:

crontab -e

添加如下行,每小时运行一次Python脚本:

0 * * * * /usr/bin/python3 /path/to/your/script.py

材料链接

总结

透视变换在图像处理领域具有重要作用,通过OpenCV提供的简单接口可以方便地完成这一操作,同时结合TDengine数据库,可以对变换过程中的数据进行高效管理和分析。

未来展望

未来,随着AR/VR技术的发展,透视变换的算法将会进一步优化,以支持更高精度和实时性的需求。同时,结合机器学习技术,自动化透视变换的应用前景也非常广阔。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。