前言:
最近在做透视变换,初次尝试是使用Pillow的transform方法,但是该方法在变换以后,由于需要提前设置变换后的图像尺寸,所以导致变换后的图像超出尺寸的部分会发生裁剪问题,这个现象不太适合我的目的,我的目的是对png图进行透视变换,然后贴在一张图上。
后来用了opencv中的方法,这个方法不会对图像进行裁剪,但是图像会出现一些多余的透明区域,因此再进行一步根据像素值非0进行裁剪即可
import cv2 import numpy as np img = cv2.imread('sample.png') height, width, channel = img.shape # 判断是不是四通道,如果不是需要转换 if channel != 4: # 创建一个具有4通道(RGBA)的目标图像 rgba_image = np.zeros((height, width, 4), dtype=np.uint8) # 将RGB图像的通道复制到RGBA图像中 rgba_image[:, :, :3] = rgb_image # 初始化Alpha通道为不透明(255) rgba_image[:, :, 3] = 255 # 设置Alpha通道 img = rgba_image # 原目标的四个点位置,分别对应,左上角,右上角,左下角,右下角 src = np.float32([[0,0], [width, 0], [0, height], [width, height]]) #变换后的四个顶点位置,设置随机值 left_top_h = random.randint(0, int(0.35*height)) left_top_w = random.randint(0, int(0.35*width)) right_top_h = random.randint(0, int(0.35*height)) right_top_w = random.randint(int(0.65*width), width) left_button_h = random.randint(int(0.65*height), height) left_button_w = random.randint(0, int(0.35*width)) right_button_h = random.randint(int(0.65*height), height) right_button_w = random.randint(int(0.65*width), width) dst = np.float32([[left_top_w, left_top_h], [right_top_w, right_top_h], [left_button_w, left_button_h], [right_button_w, right_button_h]]) matrix = cv2.getPerspectiveTransform(src, dst) imgOutput = cv2.warpPerspective(img, matrix, (width, height)) # 对结果进行裁剪 # 查找不透明像素的边界 non_transparent_pixels = cv2.findNonZero(imgOutput[:, :, 3]) x, y, w, h = cv2.boundingRect(non_transparent_pixels) # 裁剪图像 cropped_image = imgOutput[y:y+h, x:x+w] # 保存结果 cv2.imwrite('transform.png', imgOutput) # 注意,以上是opencv的方式,如果你使用pil读取图像,返回也需要pil格式,就需要对其进行变换 # 假设pil读取png图像 pil_img = Image.open('sample.png').convert('RGBA') img = cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGBA2BGRA) # 保存的时候将cv2格式转为pil imgOutput = cv2.cvtColor(imgOutput, cv2.COLOR_BGRA2RGBA) imgOutput = Image.fromarray(imgOutput)
标签:原图,random,OpenCV,button,裁剪,cv2,height,width,imgOutput From: https://www.cnblogs.com/chentiao/p/17818051.html