项目场景:
背景:
云图周边有建筑物和镜头畸变严重区域,想要把这部分裁剪掉。但是因为要上线使用,所以每张图片处理时间要尽可能短。
—
问题描述
问题:
考虑两种方式:
- 新建一张纯黑色图片,用三角函数,规定区域的像素等于原图,其他都为黑色。
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]:
#这里384和240是像素
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)
- 图层,两张图片深度嵌入,即用一张黑白灰度图嵌入云图原图中。
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为:
34.jpg为: