图片圆形裁剪遇到的问题总结

项目场景:

背景:

云图周边有建筑物和镜头畸变严重区域,想要把这部分裁剪掉。但是因为要上线使用,所以每张图片处理时间要尽可能短。
原始图片
裁剪为类似这样的

问题描述

问题:

考虑两种方式:

  1. 新建一张纯黑色图片,用三角函数,规定区域的像素等于原图,其他都为黑色。
import os, math 
from PIL import Image 
import datetime
import cv2
import numpy as np

starttime = datetime.datetime.now()
  
ima = Image.open(r'C:\Users\Phoebe942\Desktop\weathertypes\34.jpg').convert("RGBA")
size = ima.size 
print(size) 

# 因为是要圆形,所以需要正方形的图片 
r2 = min(size[0], size[1]) #1920
if size[0] != size[1]:
    #这里384240是像素
    left = (2560-1920)/2
    ima = ima.crop((left, 0, 2560-left, 1920)) #Image.crop(left, up, right, below)left:与左边界的距离up:与上边界的距离right:还是与左边界的距离below:还是与上边界的距离,简而言之就是,左上右下。

# 最后生成圆的半径
r3 = int(size[1]/2*0.6838)
imb = Image.new('RGBA', (r3*2, r3*2),(0,0,0,0))  #Image.new(mode, size, color=0)color:生成图像的颜色,默认为0,即黑色。

pima = ima.load() # 像素的访问对象 
pimb = imb.load() 
r = float(r2/2) #圆心横坐标 


pimb[i-(r-r3),j-(r-r3)] = [pima[i,j] for 
for i in range(r2): 
    for j in range(r2): 
        lx = abs(i-r) #到圆心距离的横坐标 
        ly = abs(j-r)#到圆心距离的纵坐标 
        l = (pow(lx,2) + pow(ly,2))**0.5 # 三角函数 半径       
        if l < r3: 
            pimb[i-(r-r3),j-(r-r3)] = pima[i,j] 
imb.save(r"C:\Users\Phoebe942\Desktop\10547732_3\7.png")

endtime = datetime.datetime.now()

print (endtime - starttime)

  1. 图层,两张图片深度嵌入,即用一张黑白灰度图嵌入云图原图中。
from PIL import Image, ImageDraw
import numpy as np
import cv2
# 计算需要裁剪的区域
crop_left = (2560-1920)/2+180
crop_top = 180
crop_right = 2560-crop_left
crop_bottom = 1920-crop_top

img_path = 'C:/Users/Phoebe942/Desktop/weathertypes/34.jpg'
img = Image.open(img_path).convert("RGB")
cropped = img.crop((crop_left, crop_top, crop_right, crop_bottom))
npImage = np.array(cropped)
h, w = cropped.size
print(h,w)
cv2.namedWindow("images0",cv2.WINDOW_NORMAL)
cv2.resizeWindow("images0",int(h/3),int(w/3))
cv2.imshow("images0", np.hstack([npImage]))
cv2.waitKey(0)
cv2.destroyAllWindows()

# 新建圆形遮罩图层
alpha = Image.new('L', cropped.size, 0)
draw = ImageDraw.Draw(alpha)
draw.pieslice([0, 0, h, w], 0, 360, fill="white")
npAlpha = np.array(alpha)
cv2.imwrite(r'C:\Users\Phoebe942\Desktop\000.png',npAlpha)
npImage = np.dstack((npImage,npAlpha)) #沿深度方向进行拼接

cv2.namedWindow("images1",cv2.WINDOW_NORMAL)
cv2.resizeWindow("images1",int(h/3),int(w/3))
cv2.imshow("images1", npAlpha)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 保存图片结果
Image.fromarray(npImage).save(r'C:\Users\Phoebe942\Desktop\cut.png')

原因分析:

第一种方式可以处理,但是处理一张图片所需时间为4.5s,第二种方式保存的图片是对的,但是用imshow显示的时候是原图。不是已经处理过的图片。

两张图片深度嵌入,采用的是

npImage = np.dstack((npImage,npAlpha)) #沿深度方向进行拼接
import numpy as np
a = [[[1,2,3,4],[1,2,3,4],[1,2,3,4]],[[1,2,3,4],[1,2,3,4],[1,2,3,4]]]
b = [[[1,2,3,4],[1,2,3,4],[1,2,3,4]],[[1,2,3,4],[1,2,3,4],[1,2,3,4]]]
c = np.dstack((a,b))
print(np.array(a).shape,np.array(b).shape,np.array(c).shape)
#输出
(2, 3, 4) (2, 3, 4) (2, 3, 8)

也就是说,当两个图片深度嵌入时,若(1920,1920,3)“RGB”模式的彩色图与(1920,1920,1)“L”模式的灰度图嵌入一起,则得到的是(1920,1920,4)的’‘RGBA’格式的图片。但是CV2读取图片往往用RGB格式,会省略第四通道,所以读取为原图,但保存到电脑上的图片是RGBA的。


---

# 解决方案:
>提示:目前无特别完美的解决方法:只有尽可能缩短时间

第一步:新建一个黑色图片,与原图一样大,保存,每次使用调取,不用每次都新建。
第二步:按方法1处理。

```python
import os, math 
from PIL import Image 
import datetime
import cv2
import numpy as np

starttime = datetime.datetime.now()
a00 = cv2.imread(r"C:\Users\Phoebe942\Desktop\10547732_3\00.jpg")
img = cv2.imread(r"C:\Users\Phoebe942\Desktop\weathertypes\34.jpg")
#print(a00.shape,img.shape)
for i in range(r2): 
    for j in range(r2): 
        #abs(i-r) #到圆心距离的横坐标 
        #abs(j-r)#到圆心距离的纵坐标 
        l = (pow((i-r),2) + pow((j-r),2))**0.5 # 三角函数 半径       
        if l < r3: 
            a00[i-304,j-304] = img[i,j] 
imb.save(r"C:\Users\Phoebe942\Desktop\10547732_3\001.png")
endtime = datetime.datetime.now()
print (endtime - starttime)

#计算时间为:0:00:04.293515
其中00.jpg为:
在这(1312,1312)
34.jpg为:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值