利用python-opencv 做出图像/视频的哈哈镜效果
@[TOP](利用python-opencv 做出图像/视频的哈哈镜效果)
引言
在进行过相机校准的学习之后,我们已经理解了相机的外参/内参矩阵。
关于相机校准的原理以及内外参矩阵的介绍可以参考
我们可以做一个简单的应用:通过opencv-python cv 弯曲所生成的图像。
我们来看看原理:
原理
构建哈哈镜需要三个步骤:
构建一个虚拟相机
对于图像输入,先由图片定义虚拟世界坐标(图片位于XOY平面),将变形函数应用至其上(XOY以z轴为法线,可用plane.Z表示),
最后经过虚拟相机的参数矩阵转换到像素坐标并最终输出。
注:后面会看到,利用vcam包的虚拟相机可以让这个过程变得十分简单,但编写创建虚拟相机代码的过程有助于让我们更好地理解相机校准章节的内容
步骤
1.虚拟相机构建
我们需要构造外参矩阵M1,内参矩阵K,复合成为投影矩阵P。
来看代码:
#This program can create a vitual camera
import numpy as np
import cv2 as cv# Translation Matrix T
T=np.array([1,0,0,Tx],[0,1,0,Ty],[0,0,1,Tz])# Rotation Matrix R ,liberty degree is 3
# Every Rotation in a 3D space could be seperate to 3 diffrent Rotation transformation around 3 axis xyz orthogonal,
# So the Rotation Matrix is the product of 3 Rotation Matrix R=Rx*Ry*Rz
Rx = np.array([[1, 0, 0], [0, math.cos(alpha), -math.sin(alpha)], [0, math.sin(alpha), math.cos(alpha)]])Ry = np.array([[math.cos(beta), 0, -math.sin(beta)],[0, 1, 0],[math.sin(beta),0,math.cos(beta)]])Rz = np.array([[math.cos(gamma), -math.sin(gamma), 0],[math.sin(gamma),math.cos(gamma), 0],[0, 0, 1]])R = np.matmul(Rx, np.matmul(Ry, Rz))# Extrinsic Matrix M1
M1=np.matmul(R,T)# Intrinsic Matrix K
K=np.array([fx,0,ox],[0,fy,y],[0,0,1])# Final Matrix
P=np.matmul(K,M1)
可以看到我们先构建平移矩阵T(3x4),然后构建旋转矩阵R(由3个绕xyz轴的旋转矩阵复合而成)。
内参矩阵的结构可以参考相机校准的文章。
2.定义3D表面、
我们用numpy的meshgrid去构造3D表面,格数为输入图片的像素数量。然后reshape去变换为列向量,用np.concatenate去合并向量,最后用刚刚得到的P矩阵去把得到的3D坐标投影到像素坐标上
#input image
image=cv.imread('args')H,W=image.shape[:2]x=np.linspace(-W/2,W/2,W)
y=np.linspace(-H/2,H/2,H)xv,yv=np.meshgrid(x,y)
#XY colomn vector
X=xv.reshape(-1,1)
Y=yv.reshape(-1,1)# Plan Z=1,but we write 0*X to make it a vectcor
Z=0*X+1pts3d = np.concatenate(([X],[Y],[Z],[X*0+1]))[:,:,0]pts2d = np.matmul(P,pts3d)
u = pts2d[0,:]/(pts2d[2,:]+0.00000001)
v = pts2d[1,:]/(pts2d[2,:]+0.00000001)
3.图像重映射
重映射通过将输入图像的每个像素从其原始位置移动到由重映射功能定义的新位置来生成新图像。
这种数学定义是自然的,map_x和map_y为我们指出了像素(x,y)的像。然而基于图像的source image和destination image的尺寸差异,我们可能得到非整数的map_x和map_y,这将在目标图像上产生“holes”,既没有原像的点,这是我们所不愿意看到的。
因此我们决定采用如下的数学定义:
这种方式被称为“inverse warping”。
当dst维度大于src时,虽然会产生多对一的可能性,但是至少避免了产生holes。
从2D投影点pts2d中提取map_x,map_y。并将这两个参数传递给remap函数,作用在image上即可。
# Get mapx and mapy from the 2d projected points
map_x,map_y = c1.getMaps(pts2d)# Applying remap function to input image (img) to generate the funny mirror effect
output = cv2.remap(img,map_x,map_y,interpolation=cv2.INTER_LINEAR)cv2.imshow("Funny mirror",output)
cv2.waitKey(0)
利用vcam包的简单版本
vcam的简单配置
利用pip即可自动安装vcam
pip install vcam
1.图像扭曲
vcam为我们提供了非常简洁的代码包,我们仅需要输入想要得到的像素宽高即可构建虚拟相机:
camera1=vcam(H=H,W=W)
用这个虚拟相机,我们可以直接把3D点投影到像素坐标
pts2d = camera1.project(pts3d)
来看完整代码:
import numpy as np
import cv2 as cv
from vcam import vcam,meshGenimg=cv.imread('Huashengmi.jpg')
# Resize the image to a suitable size
img=cv.resize(img,(400,400))# Get the width and height of the image
H,W=img.shape[:2]# Creation of the virtual camera
camera1=vcam(H=H,W=W)# Generate the plan
plane=meshGen(H,W)# Apply the warp function to the plan XOY
plane.Z=np.sin(8*np.pi*(plane.X/plane.W))# Some diffrent functions here
# plane.Z -= 100*np.sqrt((plane.X*1.0/plane.W)**2+(plane.Y*1.0/plane.H)**2)
# plane.Z += 20*np.exp(-0.5*((plane.X*1.0/plane.W)/0.1)**2)/(0.1*np.sqrt(2*np.pi))pts3d=plane.getPlane()# project the 3D points to the pixel coordinates
pts2d=camera1.project(pts3d)# Get map_x and map_y from 2D points
map_x,map_y=camera1.getMaps(pts2d)output=cv.remap(img,map_x,map_y,interpolation=cv.INTER_LINEAR)
# The image captured is mirrored, use cv2.flip to flip it
output=cv.flip(output,1)# Display the final image
cv.imshow("Img",output)
cv.waitKey(0)
注释已经比较详尽,我们提供了几个扭曲函数并且利用反转函数去反转相机成的倒像。
2.视频扭曲
用cv2.Videocapture去获取前置摄像头的图像,进行上述步骤即可用电脑实现“哈哈镜”的效果:
import numpy as np
import cv2 as cv
from vcam import vcam,meshGen# Activate the front cameracap=cv.VideoCapture(0)while True:# Capture frames from the videoret,frame=cap.read()# Check if the capture was successfulif not ret :print("Failed to capture the frames from camera")# Resize the frames (Not really necessary)frame=cv.resize(frame,(800,600))# Get the width and height of the imageH,W=frame.shape[:2]# Creation of the virtual cameracamera1=vcam(H=H,W=W)# Generate the planplane=meshGen(H,W)# Apply the warp function to the plan XOYplane.Z=10*np.sin(6*np.pi*(plane.X/plane.W))# Some diffrent functions here# plane.Z -= 100*np.sqrt((plane.X*1.0/plane.W)**2+(plane.Y*1.0/plane.H)**2)# plane.Z += 20*np.exp(-0.5*((plane.X*1.0/plane.W)/0.1)**2)/(0.1*np.sqrt(2*np.pi))pts3d=plane.getPlane()# project the 3D points to the pixel coordinatespts2d=camera1.project(pts3d)# Get map_x and map_y from 2D pointsmap_x,map_y=camera1.getMaps(pts2d)output=cv.remap(frame,map_x,map_y,interpolation=cv.INTER_LINEAR)# The image captured is mirrored, use cv2.flip to flip itoutput=cv.flip(output,1)# Display the current framecv.imshow("Funny mirror",output)cv.waitKey(20)
我的摄像头输出图像时4:3的,我从480x640放大到了800x600
至此我们已经学会了简单的图像变形处理,接下来我可能会学习“镜像透视法”的图像扭曲,利用findhomography去处理图像。
参考了learn-opencv的Funny mirrors 教程:learn opencv Funny Mirrors
利用python-opencv 做出图像/视频的哈哈镜效果相关推荐
- 利用Python+OpenCV对图像加密/解密
原文地址:利用Python.OpenCV对图像加密解密 | QuantumCloud蕴藏一个有趣.不难且实用的理论知识https://myblog.quantumcloud.top/2021/05/1 ...
- 利用python opencv实现图像自适应二值化
对灰度图像利用阈值得到一个二值化的图像,是常最常用的图像处理技术之一.例如,灰度大于127的图像设置为1.小于127的设置为0,这种处理便是固定阈值127的二值化处理. 自适应的二值化处理不同于固定阈 ...
- Python+OpenCV:图像金字塔
Python+OpenCV:图像金字塔 理论 通常情况下,我们使用固定大小的图像.但在某些情况下,我们需要处理(相同的)不同分辨率的图像. 例如,当搜索图像中的某些东西时,比如脸,我们不确定该物体在图 ...
- Python+OpenCV判断图像是黑底还是白底
前言 本篇博客使用Python+OpenCV判断图像是黑底还是白底,利用图像对角线上的黑白像素点个数进行判断,详情见下文. 本篇博客内容包含代码逻辑.说明.依赖.实现,这几部分.代码实现部分包含2种实 ...
- Python+OpenCV:图像修复(Image Inpainting)
Python+OpenCV:图像修复(Image Inpainting) 理论 Most of you will have some old degraded photos at your home ...
- Python+OpenCV:图像二进制鲁棒独立基本特征(BRIEF, Binary Robust Independent Elementary Features)
Python+OpenCV:图像二进制鲁棒独立基本特征(BRIEF, Binary Robust Independent Elementary Features) 理论 We know SIFT us ...
- Python+OpenCV:图像快速角点检测算法(FAST Algorithm for Corner Detection)
Python+OpenCV:图像快速角点检测算法(FAST Algorithm for Corner Detection) 理论 Feature Detection using FAST Select ...
- Python+OpenCV:图像Shi-Tomasi角点检测器
Python+OpenCV:图像Shi-Tomasi角点检测器 理论 The scoring function in Harris Corner Detector was given by: Inst ...
- Python+OpenCV:图像Harris角点检测(Harris Corner Detection)
Python+OpenCV:图像Harris角点检测(Harris Corner Detection) 理论 corners are regions in the image with large v ...
最新文章
- Linux学习(十一)---进程管理
- 生成对抗网络(GAN)应用于图像分类
- Leetcode114二叉树转链表-树中修改
- zTree 优秀的jquery树插件
- 创建一个Flash站点的十大技巧
- 基于权重的节点驱逐 - Oracle RAC 12.2 新特性
- 保研到国防科大计算机,拿奖到“手软” 国防科技大学这个“学霸宿舍”集体保研...
- java 常量 类型_Java的常量及数据类型。
- Android 获取有规律资源Id解决方案
- C++11 chrono库
- JAVA--set用法
- win98/win95
- 2020成人高考计算机基础知识题库,成人高考计算机考试全套题库
- 【sketchup 2021】草图大师的编辑工具2【路径跟随、偏移与轴、卷尺工具和尺寸、绘制参考线】
- java if 终止_java中跳出或终止if语句的方法
- 家庭局域网_组建家庭无线局域网需要哪些硬件设备?
- 【镜像取证篇】常见镜像文件类型
- 利用Photoshop对证件照换底且抠出头发丝
- 一文理解CPU进行简单加法(计算机组成原理5.1CPU的功能和基本结构)
- 罗技 连点 脚本_走心分享!当评测罗技MASTER 3遇上ANYWHERE 3