重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
窗口的透视变换效果
创新互联公司是一家集网站建设,和平企业网站建设,和平品牌网站建设,网站定制,和平网站建设报价,网络营销,网络优化,和平网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。 当我们点击Win10的UWP应用中的小部件时,会发现小部件会朝着鼠标点击位置凹陷下去,而且不同的点击位置对应着不同的凹陷情况,看起来就好像小部件在屏幕上不只有x轴和y轴,甚至还有一个z轴。要做到这一点,其实只要对窗口进行透视变换即可。下面是对Qt的窗口和按钮进行透视变换的效果:
具体代码
1.下面先定义一个类,它的作用是将传入的 QPixmap
转换为numpy
数组,然后用 opencv
的 warpPerspective
对数组进行透视变换,最后再将 numpy
数组转为 QPixmap
并返回;
# coding:utf-8 import cv2 as cv import numpy from PyQt5.QtGui import QImage, QPixmap class PixmapPerspectiveTransform: """ 透视变换基类 """ def __init__(self, pixmap=None): """ 实例化透视变换对象\n Parameter --------- src : numpy数组 """ self.pixmap = pixmap def setPixmap(self, pixmap: QPixmap): """ 设置被变换的QPixmap """ self.pixmap = QPixmap self.src=self.transQPixmapToNdarray(pixmap) self.height, self.width = self.src.shape[:2] # 变换前后的边角坐标 self.srcPoints = numpy.float32( [[0, 0], [self.width - 1, 0], [0, self.height - 1], [self.width - 1, self.height - 1]]) def setDstPoints(self, leftTop: list, rightTop, leftBottom, rightBottom): """ 设置变换后的边角坐标 """ self.dstPoints = numpy.float32( [leftTop, rightTop, leftBottom, rightBottom]) def getPerspectiveTransform(self, imWidth, imHeight, borderMode=cv.BORDER_CONSTANT, borderValue=[255, 255, 255, 0]) -> QPixmap: """ 透视变换图像,返回QPixmap\n Parameters ---------- imWidth : 变换后的图像宽度\n imHeight : 变换后的图像高度\n borderMode : 边框插值方式\n borderValue : 边框颜色 """ # 如果是jpg需要加上一个透明通道 if self.src.shape[-1] == 3: self.src = cv.cvtColor(self.src, cv.COLOR_BGR2BGRA) # 透视变换矩阵 perspectiveMatrix = cv.getPerspectiveTransform( self.srcPoints, self.dstPoints) # 执行变换 self.dst = cv.warpPerspective(self.src, perspectiveMatrix, ( imWidth, imHeight), borderMode=borderMode, borderValue=borderValue) # 将ndarray转换为QPixmap return self.transNdarrayToQPixmap(self.dst) def transQPixmapToNdarray(self, pixmap: QPixmap): """ 将QPixmap转换为numpy数组 """ width, height = pixmap.width(), pixmap.height() channels_count = 4 image = pixmap.toImage() # type:QImage s = image.bits().asstring(height * width * channels_count) # 得到BGRA格式数组 array = numpy.fromstring(s, numpy.uint8).reshape( (height, width, channels_count)) return array def transNdarrayToQPixmap(self, array): """ 将numpy数组转换为QPixmap """ height, width, bytesPerComponent = array.shape bytesPerLine = 4 * width # 默认数组维度为 m*n*4 dst = cv.cvtColor(array, cv.COLOR_BGRA2RGBA) pix = QPixmap.fromImage( QImage(dst.data, width, height, bytesPerLine, QImage.Format_RGBA8888)) return pix