使用cv2将图片转正

这篇具有很好参考价值的文章主要介绍了使用cv2将图片转正。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

要点:

参考:如何用Python-OpenCV实现图片倾斜调整?


一 图片转正

比如一张纸的照片是倾斜的,用OpenCV如何实现自动检测出纸的轮廓并调整倾斜角度,让照片变“正”。

import cv2
import numpy as np

def click(event,x,y,flags,param):
    if event==cv2.EVENT_LBUTTONDOWN:
        if len(pts)<4:
            pts.append([x,y])# 只记录前四次鼠标左击的位置
            cv2.circle(img,(x,y),1,(0,0,0))
            cv2.imshow('img1',img)
        else:
            cv2.destroyWindow('img1')# 第五次鼠标左击直接关闭图片窗口

img=cv2.imread('files.jpg')
pts=[]
cv2.namedWindow('img1')
cv2.setMouseCallback('img1',click)
cv2.imshow('img1',img)
cv2.waitKey(0)
pts.sort(reverse=False)
print(pts)
width,height=250,350
pts1=np.float32(pts)
pts2=np.float32([[0,0],[width,0],[0,height],[width,height]])
matrix=cv2.getPerspectiveTransform(pts1,pts2)
img2=cv2.warpPerspective(img,matrix,(width,height))
cv2.imshow('img2',img2)
cv2.waitKey(0)

二 透视变换demo

参考:python opencv实现图像矫正功能_python_脚本之家

import cv2
import numpy as np
 
img = cv2.imread('/home/pzs/图片/1.jpeg')
 
result3 = img.copy()
 
img = cv2.GaussianBlur(img,(3,3),0)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
 
edges = cv2.Canny(gray,50,150,apertureSize = 3)
cv2.imwrite("canny.jpg", edges)
 
src = np.float32([[207, 151], [517, 285], [17, 601], [343, 731]])
dst = np.float32([[0, 0], [337, 0], [0, 488], [337, 488]])
m = cv2.getPerspectiveTransform(src, dst)
result = cv2.warpPerspective(result3, m, (337, 488))
cv2.imshow("result", result)
cv2.waitKey(0)

2.1 如何找到目标的4个顶点

如何找到这4个顶点:
方法有很多种,如:直线检测,轮廓检测,最小外接矩形等。

使用轮廓检测方式:

import cv2
import imutils
 
img = cv2.imread('1.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
dilate = cv2.dilate(blurred, cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)))
edged = cv2.Canny(dilate, 30, 120, 3)            # 边缘检测
 
cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)  # 轮廓检测
cnts = cnts[0] if imutils.is_cv2() else cnts[1]  # 判断是opencv2还是opencv3
docCnt = None
 
if len(cnts) > 0:
    cnts = sorted(cnts, key=cv2.contourArea, reverse=True) # 根据轮廓面积从大到小排序
    for c in cnts:
        peri = cv2.arcLength(c, True)                                       # 计算轮廓周长
        approx = cv2.approxPolyDP(c, 0.02*peri, True)           # 轮廓多边形拟合
        # 轮廓为4个点表示找到纸张
        if len(approx) == 4:
            docCnt = approx
            break
 
for peak in docCnt:
    peak = peak[0]
    cv2.circle(img, tuple(peak), 10, (255, 0, 0))
 
cv2.imshow('img', img)
cv2.waitKey(0)

2.2 cv2.approxPolyDP() 多边形逼近

重点讲解这个函数

作用:

对目标图像进行近似多边形拟合,使用一个较少顶点的多边形去拟合一个曲线轮廓,要求拟合曲线与实际轮廓曲线的距离小于某一阀值。

函数原形:

cv2.approxPolyDP(curve, epsilon, closed) -> approxCurve

参数:

curve : 图像轮廓点集,一般由轮廓检测得到
epsilon : 原始曲线与近似曲线的最大距离,参数越小,两直线越接近
closed : 得到的近似曲线是否封闭,一般为True

返回值:

approxCurve :返回的拟合后的多边形顶点集。

三 透视变换

之前都是通过仿射变换方式,转正后截取。

但是参考了 Cropping Rotated Rectangles from Image with OpenCV
这篇文章,主要就是运用了透视变换,非常巧妙

# -*- coding: utf-8 -*-
"""
   File Name:     rotation_v3
   Description :
   date:          2019/5/10
"""
import cv2
import numpy as np
import matplotlib.pylab as plt
import time

img=cv2.imread('3_75.jpg')
# img=img[14:-15,13:-14]
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
print("num of contours: {}".format(len(contours)))


rect = cv2.minAreaRect(contours[1])  #获取蓝色矩形的中心点、宽高、角度


'''
retc=((202.82777404785156, 94.020751953125),
 (38.13406753540039, 276.02105712890625),
 -75.0685806274414)


width = int(rect[1][0])
height = int(rect[1][1])
angle = rect[2]
print(angle)

if width < height:  #计算角度,为后续做准备
  angle = angle - 90
print(angle)
'''
if rect[-1] < -45 or rect[-1] > 45:
	rect = (rect[0], (rect[1][1], rect[1][0]), rect[2] - 90)
angle = rect[2]
width = int(rect[1][0])
height = int(rect[1][1])
# if  angle < -45:
#     angle += 90.0
#        #保证旋转为水平
# width,height = height,width
src_pts = cv2.boxPoints(rect)

# box = cv2.boxPoints(rect)
# box = np.int0(box)
# cv2.drawContours(img_box, [box], 0, (0,255,0), 2) 

dst_pts = np.array([[0, height],
                    [0, 0],
                    [width, 0],
                    [width, height]], dtype="float32")
M = cv2.getPerspectiveTransform(src_pts, dst_pts)
warped = cv2.warpPerspective(img, M, (width, height))

if angle<=-90:  #对-90度以上图片的竖直结果转正
    warped = cv2.transpose(warped)
    warped = cv2.flip(warped, 0)  # 逆时针转90度,如果想顺时针,则0改为1
    # warped=warped.transpose
cv2.imshow('wr1',warped)
cv2.waitKey(0)

仿射变换是二维变换,就是在一个平面上,可以通过三个定点,随意的拉拽到想要的形状,但是不能拿起来,所以他的投影还是他拉拽的本身。

透视变换 是三维变换,就是可以拿起来,随意平行、竖直、翻转一定角度等,就是可以拉拽4个定点,所以它的投影会变成不规则的形状,更高级一点。


四 根据任意矩形(四点坐标)截取指定区域图像

参考资料: 根据任意矩形(四点坐标)截取指定区域图像文章来源地址https://www.toymoban.com/news/detail-451368.html

def CutImgeByBox(output,box):
    """
    根据任意内接矩形,四点(顺时针)box[[x1,y2],[x2,y2],[x3,y3],[x4,y4]],从输入图像中,截取图像
    """
    if type(box)==type([]):    
        pts1 = np.float32(box)
        if pts1.shape==(4,2):
            # 变换后的矩形四个顶点坐标    
            dy=int(np.sqrt((box[0][0]-box[1][0])**2+(box[0][1]-box[1][1])**2))
            dx=int(np.sqrt((box[1][0]-box[2][0])**2+(box[1][1]-box[2][1])**2))   
            pts2 = np.float32([[1, dy+1],
                          [1, 1],
                          [1+dx, 1],
                          [1+dx, 1+dy]]) 
            M = cv2.getPerspectiveTransform(pts1,pts2)
            dst = cv2.warpPerspective(output, M, (output.shape[1],output.shape[0]))   
            target = dst[int(pts2[1][1]):int(pts2[0][1]),int(pts2[1][0]):int(pts2[2][0]),:]
            return True,target
        else:
            print("box shape is wrong ,must be list as (4,2)")
            return False,output
    else:
        print("box type is wrong,must be list as [[x1,y2],[x2,y2],[x3,y3],[x4,y4]]")
        return False,output

到了这里,关于使用cv2将图片转正的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 图片缩放cv2.resize()详解

    resize(src, dsize, dst=None, fx=None, fy=None, interpolation=None) 参数解释 : 参数 解释 src 输入原图像 dsize 输出图像的大小,方式:(宽,高) fx width方向的缩放比例 fy height方向的缩放比例 interpolation 插值方式,默认为双线性插值 scr、dsize是必传参数,fx、fy、interpolation是可选参数。 图片进

    2023年04月19日
    浏览(30)
  • cv2 保存图片RGB BGR

    原图: cv2.imrite之后的图: 可以看到前后图片一样,我们都知道cv2 .imread读取进来的图像是BGR格式,而cv2.imrite保存的时候也需要BGR格式,这样保证颜色通道顺序一致。 通常情况下,我们都需要转换成RGB的格式进行后续处理,看下面的例子 而保存的图像却是: 可以看到颜色前

    2024年02月12日
    浏览(37)
  • cv2问题:AttributeError: ‘NoneType‘ object has no attribute ‘shape‘及CV2显示、保存图片

    输出: 原因: 图片路径中存在中文,改成英文就ok了。 注意: img.shape 的返回值是(像素h, 像素w, 图片通道数)格式的元组。 补充: 1.读取图片 参数解析: 2.显示图片 cv2.imshow()函数在一个窗口中显示图片,窗口自适应图片的大小 参数: 注意: 因为我们的程序是顺序执行,

    2024年02月14日
    浏览(28)
  • Python 将图片流转为其CV2矩阵数据信息

     我们常常使用 Python  将图片流转为其CV2矩阵数据信息    以便使用cv2 去实现对图片的处理   以下我整理了两个方法   一个用于将图片二进制流转为CV2格式   一个方法是将CV2数据转化为图片二进制流    如下:

    2024年02月13日
    浏览(50)
  • opencv导入图片时,cv2后面无法添加imread的问题的解决方法

    当使用cv2导入图片的时候,发现cv2.imread()被标明高亮,无法使用imread,resize等方法  针对这个问题,解决方法如下: 首先在我们的Python安装路径下面找到cv2(安装anaconda的也是如此,找到相应路径),    在这里可以看到一个.pyd文件,将这个文件直接复制到site-packages路径

    2024年02月11日
    浏览(42)
  • cv2保存图片类型错误执行报错cv2. error: OpenCV(4.6.0) :-1: error: (-5:Bad argument) in function ‘imwrite‘ - img i

    硬件环境(Ascend/GPU/CPU): GPU 软件环境: – MindSpore 版本: 1.7.0 执行模式: 静态图(GRAPH) – Python 版本: 3.7.6 – 操作系统平台: linux 将优化好的图像用cv2进行图片保存,由于没有将tensor转换为numpy,导致cv2.imwrite运行失败。 adversarial_tensor, mask_tensor = adversarial.train(attack_method) cv2.imwrit

    2024年02月17日
    浏览(43)
  • opencv视频截取每一帧并保存为图片python代码CV2实现练习

    当涉及到视频处理时,Python中的OpenCV库提供了强大的功能,可以方便地从视频中截取每一帧并将其保存为图片。这是一个很有趣的练习,可以让你更深入地了解图像处理和多媒体操作。 使用OpenCV库,你可以轻松地读取视频文件,并在循环中逐帧读取视频的每一帧。随后,你可

    2024年02月12日
    浏览(40)
  • 关于OpenCV中cv2.imwrite保存的图片是全黑色的解决方案

    原因:image图片是0-255,而imwrite保存图片的时候把图片标准化了,也就变为0-1,对于这个问题,只需要修改一下imwrite的输入就好,也就是括号后半部分那个参数*255,如下: 注意:括号里边的前半部分是自己起的文件名,后半部分“img_light”改成你自己的图像名。 比如我读入

    2024年02月16日
    浏览(31)
  • 解决python-opencv:(-215:Assertion failed) _img.empty() in function ‘cv::imwrite‘在将视频分成帧图片,写入时出现的问题

    最近在搞视频检测问题,在用到将视频分帧保存为图片时,图片可以保存,但是会出现(-215:Assertion failed) !_img.empty() in function \\\'cv::imwrite\\\'问题而不能正常运行,在检查代码、检查路径等措施均无果后,了解了视频分帧的原理后,才解决了问题,就这一个问题,解决了两天才解决

    2024年02月15日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包