不用 PS 抠图,Python + OpenCV 实现自动海报场景替换!

简介: 现存在一个问题,就下面图片中的两本书而言,怎样快速让中间边的书本与左边书本对齐(最终效果能实现两张图片重叠(最终结果为右图)),进行的图像转变可旋转、平移、缩放、形变。

现存在一个问题,就下面图片中的两本书而言,怎样快速让中间边的书本与左边书本对齐(最终效果能实现两张图片重叠(最终结果为右图)),进行的图像转变可旋转、平移、缩放、形变。

微信图片_20220520113723.jpg

本文主要内容就是介绍利用 Opencv 来怎样解决上面的问题,解决这个问题需要三步

  • 确定至少四组对应点坐标
  • 找到一个转换矩阵;
  • 把找到的转换矩阵应用到 Moving Image(需要移动的图片) 上,实现图像对齐

图片旋转、平移、缩放等操作的主要目的,就是要最终实现两图像中点对点一一映射关系,图像映射本质上就是像素点转换

微信图片_20220520113725.jpg

图中标记了其中四组对应点,分别标为不同的颜色,分别标为红、橙、黄和绿四种颜色;比如这里的微信图片_20220520113727.png微信图片_20220520113728.png 是就是一组对应点,图片经过转换之后   点 必须映射到 点位置。

涉及图片中点坐标变换,都需要借助于 矩阵 运算,这里探究的图像维度都属于二维,坐标只需要 即可

面向此类转换问题,Homography 转换 ( 3 × 3 矩阵) 可用于解决此类转化问题,用来解决点对点映射问题,Homography  矩阵可写作下列方式:

微信图片_20220520113730.png

微信图片_20220520113731.png微信图片_20220520113734.png  作为对应点,则 Homography  的的应用 如下:

微信图片_20220520113735.png

而矩阵 H  参数的确定至少需要 4 组对应点,因此在计算 H 时至少要找到 4 组对应点;找到的对应点组数越多,计算得到的 H 会越精确,最终的转换效果也就会越好。

下面用 Opencv + Python 来实现上面图片中的书籍的对齐,

import cv2
import numpy as np
if __name__ =='__main__':
    #图片读取
    img_src = cv2.imread("D:/book2.jpg")
    position_src = np.array([[141,131],[480,159],[493,630],[64,601]],dtype = float)
    img_dst = cv2.imread("D:/book1.jpg")
    position_dst = np.array([[318,256],[543,372],[316,670],[73,473]],dtype = float)
    #计算转换矩阵
    h,status = cv2.findHomography(position_src,position_dst)
    #对图片进行仿射变换
    out_img = cv2.warpPerspective(img_src,h,(img_dst.shape[1],img_dst.shape[0]))
    #Display images;
    cv2.imshow("Source image",img_src)
    cv2.imshow("Destination Image",img_dst)
    cv2.imshow("Warped Source Image",out_img)
    cv2.waitKey(0)

这里事先已经确定好对应的四个点的坐标,然后把这四个点的坐标带入 cv2.findHomography() 计算出转换矩阵,最后把矩阵应用到两图像中,得到最终的转换结果,

微信图片_20220520113737.jpg

这里提醒一点,warpPerspective  函数进行对图像像素进行矩阵变换时,隐藏了一个参数 Interpolator ,默认为线性插值,功能是防止像素点像素值缺失

上面小案例不方便的一点需要确定对应四个点的坐标,这个步骤是比较繁琐的,下面案例将在程序中加入交互功能,实现某个图片的自动标记点收集、标记点点转换:

微信图片_20220520113739.gif

首先需要准备两张图片,其中一张为海报,一张为需要替换的海报;关于确定点的坐标时,被替换的图片的坐标非常好确定,只需知道图片的长宽即可;

但的海报图像区域四个点是不好确定的, 这里利用 Opencv 的鼠标回调函数,监视鼠标响应,根据用户点击来收集 PIck 得到的坐标;

def mouse_handler(event,x,y,flags,data):
    if event ==cv2.EVENT_LBUTTONDOWN:
        cv2.circle(data['im'],(x,y),3,(0,0,255),5,16)
        cv2.namedWindow("Image",0)
        cv2.imshow("Image",data['im'])
        if len(data['points']) <4:
            data['points'].append([x,y])
def get_four_points(im):
    data = {}
    data['im'] = im.copy()
    data['points'] = []
    # Set the callback function for any mouse event
    cv2.namedWindow("Image", 0)
    cv2.imshow('Image',im)
    #请注意你标记点的数据,是顺时针,需要与pst_src 方向一致
    cv2.setMouseCallback("Image",mouse_handler,data)
    cv2.waitKey(0)
    # Convert array to np.array
    #竖直方向堆叠起来;;;
    points = np.vstack(data['points']).astype(float)
    return points

坐标确定以后,接下来就很简单了,跟上个案例一样,计算变换矩阵,矩阵应用到图像旋转,最终更换海报内容也就轻松完成啦

微信图片_20220520113741.png

需要注意一点,坐标 Pick 点的顺序须与记录替换图像顶点顺序一致,否则转换图会有偏差,案例完整代码如下:

if __name__ =='__main__':
    img_src = cv2.imread("D:/first-image.jpg")
    size = img_src.shape
    # 取得四个坐标
    pst_src = np.array(
        [
            [0,0],[size[1]-1,0],
            [size[1]-1,size[0]-1],
            [0,size[0]-1]
         ],dtype=float
    )
    #Read the destination image
    img_dst = cv2.imread("D:/times-square.jpg")
    print("Click on four corners of bllboard and the press ENTER")
    four_point  = get_four_points(img_dst)
    # Calculate  Homography between  source and destination points
    h,status = cv2.findHomography(pst_src,four_point)
    im_temp = cv2.warpPerspective(img_src,h,(img_dst.shape[1],img_dst.shape[0]))
    cv2.fillConvexPoly(img_dst,four_point.astype(int),0,16)
    #add wraped source image to destination image
    img_dst = img_dst + im_temp
    cv2.namedWindow("Image", 0)
    cv2.imshow("Image",img_dst)
    cv2.waitKey(0)
相关文章
|
22天前
|
计算机视觉 Windows Python
windows下使用python + opencv读取含有中文路径的图片 和 把图片数据保存到含有中文的路径下
在Windows系统中,直接使用`cv2.imread()`和`cv2.imwrite()`处理含中文路径的图像文件时会遇到问题。读取时会返回空数据,保存时则无法正确保存至目标目录。为解决这些问题,可以使用`cv2.imdecode()`结合`np.fromfile()`来读取图像,并使用`cv2.imencode()`结合`tofile()`方法来保存图像至含中文的路径。这种方法有效避免了路径编码问题,确保图像处理流程顺畅进行。
120 1
WK
|
27天前
|
机器学习/深度学习 运维 Devops
Python语言在哪些场景下有很明显优势?
Python在多样场景中展现出显著优势,包括:通过强大的库如Pandas、NumPy、Scikit-learn等在数据科学与机器学习中的应用;利用简洁语法和集成能力在自动化运维及DevOps中的作用;借助Django、Flask等框架在网页开发与网络编程方面的表现;凭借快速迭代能力在原型开发中的效率;通过NumPy、SciPy等库在科学研究与工程计算的支持;以及因其易学特性在教育领域的普及。这些特点使Python成为多领域开发的优选语言。
WK
37 5
|
2月前
|
机器学习/深度学习 人工智能 算法
Python在计算机视觉(CV)中扮演重要角色,得益于其丰富的库如OpenCV、Pillow和Scikit-image。
【7月更文挑战第5天】Python在计算机视觉(CV)中扮演重要角色,得益于其丰富的库如OpenCV、Pillow和Scikit-image。CV涉及图像处理、模式识别和机器学习,用于图像理解和生成。Python的跨平台特性和活跃社区使其成为CV的理想工具。基本流程包括图像获取、预处理、特征提取、分类识别及图像生成。例如,面部识别通过预处理图像,使用如`cv2.CascadeClassifier`进行检测;物体检测类似,但需适应不同目标;图像生成则利用GAN创造新图像。
48 4
|
22天前
|
算法 计算机视觉 Python
python利用opencv进行相机标定获取参数,并根据畸变参数修正图像附有全部代码(流畅无痛版)
该文章详细介绍了使用Python和OpenCV进行相机标定以获取畸变参数,并提供了修正图像畸变的全部代码,包括生成棋盘图、拍摄标定图像、标定过程和畸变矫正等步骤。
python利用opencv进行相机标定获取参数,并根据畸变参数修正图像附有全部代码(流畅无痛版)
|
11天前
|
数据采集 机器学习/深度学习 搜索推荐
Python爬虫技术基础与应用场景详解
本文介绍了爬虫技术的基本概念、原理及应用场景,包括数据收集、价格监测、竞品分析和搜索引擎优化等。通过一个实战案例展示了如何使用Python爬取电商网站的商品信息。强调了在使用爬虫技术时需遵守法律法规和道德规范,确保数据抓取的合法性和合规性。
|
22天前
|
存储 编解码 API
python多种方法压缩图片,opencv、PIL、tinypng、pngquant压缩图片
python多种方法压缩图片,opencv、PIL、tinypng、pngquant压缩图片
20 1
|
22天前
|
算法 定位技术 vr&ar
一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达
一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达
100 0
一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达
WK
|
16天前
|
机器学习/深度学习 数据挖掘 测试技术
Python在移动设备上的应用场景
Python在移动设备上的应用广泛,尽管不是原生开发首选,但凭借其灵活性、跨平台特性和丰富库支持,Python在跨平台应用开发、自动化测试、设备管理、数据分析、机器学习、原型设计及教育领域展现出巨大潜力。开发者可利用Kivy、BeeWare等框架进行一次编写多平台运行的应用开发,同时Python也是自动化测试、数据分析(如使用Pandas、NumPy)及机器学习(如Scikit-learn、TensorFlow)的理想选择。此外,Python还适用于快速原型设计和教育工具开发,其简洁语法使编程学习更为便捷。随着技术进步,Python在移动设备上的应用前景将更加广阔。
WK
14 0
|
1月前
|
存储 数据库 C++
"深入剖析Python元组(tuple):与列表的对比、特性解析及高效应用场景展示"
【8月更文挑战第9天】Python元组与列表虽均用于存储元素集合,但有本质差异。元组不可变,创建后无法修改,适合保护数据不被意外更改的场景,如作字典键或传递固定值。列表则可变,支持动态增删改,适用于需频繁调整的数据集。元组因不可变性而在性能上有优势,可用于快速查找。两者各有千秋,根据具体需求选择使用。例如,元组可用于表示坐标点或日期,而列表更适合管理用户列表或库存。
39 1
|
20天前
|
机器学习/深度学习 人工智能 监控
利用Python和OpenCV实现实时人脸识别系统
【8月更文挑战第31天】本文将引导您了解如何使用Python结合OpenCV库构建一个简易的实时人脸识别系统。通过分步讲解和示例代码,我们将探索如何从摄像头捕获视频流、进行人脸检测以及识别特定个体。本教程旨在为初学者提供一条明晰的学习路径,帮助他们快速入门并实践人脸识别技术。