图像处理

处理图像:截取图像

python 的图像库(Opencv、PIL、matplotlib、skimage)使用

参考-更好
参考
cv2的记录
ret=cv2.bitwise_and(src1,src2,dst,mask) ret和dst都可以,mask相当于在src1和src2与运算结果上又进行了一次mask与运算,但是mask是单通道的。mask区域会被保存下来,其他部分编变成黑色。

matplotlib的记录
plt.imshow()显示只有0,1的图像,但是输出是紫色和黄色的。如果要展示黑白,plt.set_cmat(‘binary’),但是会把黑白反过来,masked区域为白色,其余为黑色。

一、截取图像的一部分

1.使用Pillow

1
2
3
4
5
6
7
8
from PIL import Image
img = Image.open(path)
img=img.crop((left, up, right, below))
# left:与左边界的距离
# up:与上边界的距离
# right:还是与左边界的距离
# below:还是与上边界的距离
img.save(target_path+name)

2.多边形裁剪(多边形外的其他地方透明)(python-opencv)

方法一和二的不同在于:把mask的多边形区域设置为0还是255(黑白)。 如果mask多边形区域设为0,可以直接与原图相加,该区域不变,原图其他位置变成白色;如果mask多边形区域设为255,可以与原图进行与运算,该区域不变,其他区域变成黑色
方法一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#coding=utf-7
import numpy as np
import cv2
from PIL import Image

image = cv2.imread("0.jpg")
print(image.shape)
b = np.array([[100,100], [250,100], [300,220],[100,230]], dtype = np.int32)

roi_t = []
for i in range(4):
roi_t.append(b[i])

# 生成mask,多边形区域设为255白色
roi_t = np.asarray(roi_t)
roi_t = np.expand_dims(roi_t, axis=0)
im = np.zeros(image.shape[:2], dtype = "uint8")
cv2.polylines(im, roi_t, 1, 255)
cv2.fillPoly(im, roi_t, 255)
mask = im
masked = cv2.bitwise_and(image, image, mask=mask)

#非多边形区域做透明处理
array = np.zeros((masked.shape[0], masked.shape[1], 4), np.uint8)
print(array.shape)
array[:, :, 0:3] = masked
array[:, :, 3] = 0
array[:,:,3][np.where(array[:,:,0]>2)]=255
array[:,:,3][np.where(array[:,:,1]>2)]=255
array[:,:,3][np.where(array[:,:,2]>2)]=255
cv2.imwrite('0_opencv.png',array,[cv2.IMWRITE_PNG_COMPRESSION,1]) #可以设置图像的压缩程度,9压缩程度最高。

# 使用PIL.Image 保存图片颜色发生了变化,重新读出来,与原图不一样.
#opencv的接口使用BGR,而matplotlib.pyplot 则是RGB模式
#下面代码cv2读入的是BGR模式,在opencv里面存储的是BGR,所以img用opencv输出就是正常颜色;
#而matplotlib.pyplot是RGB模式,当用cv读入,直接用matplotlib.pyplot输出,颜色就变了,所以需要调整颜色的顺序;

b,g,r,a = cv2.split(array)
img2 = cv2.merge([r,g,b,a])
print(img2.max())
image_1 = Image.fromarray(img2)
image_1.save("0_PIL.png","PNG")

new_image = cv2.imread('0_opencv.png',cv2.IMREAD_UNCHANGED) # 不加cv2.IMREAD_UNCHANGED 只能读出三个通道,透明通道不能读取
print((array==new_image).all(),new_image.shape,array.shape) # .all()全部为True,结果为True;.any()有一个为True,结果为True

cv2.imshow("cutout Image", array)

cv2.waitKey(0)
cv2.destroyAllWindows()

方法二:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#coding=utf-8
import numpy as np

import cv2
from PIL import Image

image = cv2.imread("0.jpg")

b = np.array([[100,100], [250,100], [300,220],[100,230]], dtype = np.int32)

roi_t = []
for i in range(4):
roi_t.append(b[i])

# 生成mask,,多边形区域设为0黑色
roi_t = np.asarray(roi_t)
roi_t = np.expand_dims(roi_t, axis=0)
im = np.zeros(image.shape[:3], dtype = "uint8")
im.fill(255)
cv2.polylines(im, roi_t, 1, 0)
cv2.fillPoly(im, roi_t, 0)
mask = im
masked = cv2.add(image, mask)
imp = Image.fromarray(image)

#非多边形区域做透明处理
array = np.zeros((masked.shape[0], masked.shape[1], 4), np.uint8)
array[:, :, 0:3] = masked
array[:, :, 3] = 0
array[:,:,3][np.where(array[:,:,0]<255)]=255
array[:,:,3][np.where(array[:,:,1]<255)]=255
array[:,:,3][np.where(array[:,:,2]<255)]=255
cv2.imwrite('0_opencv.png',array,[cv2.IMWRITE_PNG_COMPRESSION,1]) #可以设置图像的压缩程度,9压缩程度最高。
cv2.imshow("cutout Image", array)

cv2.waitKey(0)
cv2.destroyAllWindows()

二、修改图像大小

1.使用Pillow

1
2
3
4
5
6
7
from PIL import Image
img = Image.open(path)
reim=img.resize((128,128))
reim=img.thumnail((128,128))
#resize()方法可以缩小也可以放大,而thumbnail()方法只能缩小;
#resize()方法不会改变对象的大小,只会返回一个新的Image对象,而thumbnail()方法会直接改变对象的大小,返回值为none;
#resize()方法中的size参数直接规定了修改后的大小,而thumbnail()方法按比例缩小,size参数只规定修改后size的最大值。
Contents
  1. 1. python 的图像库(Opencv、PIL、matplotlib、skimage)使用
  2. 2. 一、截取图像的一部分
    1. 2.1. 1.使用Pillow
    2. 2.2. 2.多边形裁剪(多边形外的其他地方透明)(python-opencv)
  3. 3. 二、修改图像大小
    1. 3.1. 1.使用Pillow
|