OpenCV、PIL知识点日常总结,Bug总结【持续更新......】

1、opencv与PIL打开的图片的区别

1.1 使用opencv打开图片

1、如果图片是中文路径,则在cv2.imdecode中使用np.fromfile,如果是英文路径则使用cv2.imread()
2、opencv中的im.shape:(1080, 1920, 3),1080是height,1920是width,3是通道,
3、暂时没使用过im.size
代码:

import cv2
import numpy as np
path = r"C:\Users\9ling\Desktop\窗帘\粤东莞城区花园支行柜台外环境1_20220818165350879.jpg"
im = cv2.imdecode(np.fromfile(path), 1)
print(im.shape)  # (1080, 1920, 3)
print(im.size)  # 6220800
cv2.imshow("im", im)
cv2.imwrite("./test.jpg", im)
cv2.waitKey()
cv2.destroyAllWindows()

输出:

(1080, 1920, 3)
6220800
1.2 使用PIL.Image打开图片

1、Image打开图片使用的内部方法open;
2、im.size=(1920, 1080) ,1920是width,1080是height
3、使用plt.imshow()方法显示图片,我在pycharm中运行始终没有显示,但在jupyter可以显示,暂时不知道为啥

import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
path = r"C:\Users\9ling\Desktop\窗帘\粤东莞城区花园支行柜台外环境1_20220818165350879.jpg"
im = Image.open(path)
print(im.size)  # (1920, 1080)
print(np.shape(im))  # (1080, 1920, 3)
im.save(r"C:\Users\9ling\Desktop\chuanglian.jpg")
plt.imshow(im)
im.close()

输出:

(1920, 1080)
(1080, 1920, 3)

参考:链接

2、cv2.error: OpenCV(4.5.5) : -1: error: (-5:Bad argument) in function ‘rectangle‘

我卸载了我目前版本的opencv,版本为: 4.6.0.66,然后下载了这个版本,
查看opencv的版本:

pip show opencv_python

卸载opencv:

pip uninstall opencv_python

安装opencv:

pip install opencv_python==4.4.0.46

参考:链接

3、报错TypeError: Expected Ptr<cv::UMat> for argument ‘src‘

参考:链接

4、cv2.resize()

cv2.resize(image, (width, height), interpolation=INTER_LINEAR)

要注意第2个参数是:(width, height)

5、关于PIL说的不错的链接

参考:链接1链接2

6、cv2.flip()和cv2.rotate()

参考:链接

7、BUG:【cv2.error: OpenCV(4.1.2) C:\projects\opencv-python\opencv\modules\imgcodecs\src\loadsave.cpp:715: error: (-215:Assertion failed) !_img.empty() in function ‘cv::imwrite’】

出现的原因如下:
1、图片路径写入中文;
2、写入图片本身的错误 ,如截取图片大小超界;

参考链接:链接

8、cv2如何改变窗口的大小

只增加如下代码即可:

# 改变窗口大小
cv2.namedWindow("im", 0)
cv2.resizeWindow("im", 1066, 600)
cv2.imshow("im", im)

参考:链接

9、cv2.rectangle()

参考:链接

10、openCV查看像素值

import cv2
img= cv2.imread('290.png')          #定义图片位置
#img= cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  #转化为灰度图 因为我读取的直接是灰度标签图片就不用转化了
def onmouse(event, x, y, flags, param):   #标准鼠标交互函数
  if event==cv2.EVENT_MOUSEMOVE:      #当鼠标移动时
    print(img[y,x])           #显示鼠标所在像素的数值,注意像素表示方法和坐标位置的不同
def main():
  cv2.namedWindow("img")          #构建窗口
  cv2.setMouseCallback("img", onmouse)   #回调绑定窗口
  while True:               #无限循环
    cv2.imshow("img",img)        #显示图像
    if cv2.waitKey() == ord('q'):break  #按下‘q'键,退出
  cv2.destroyAllWindows()         #关闭窗口
if __name__ == '__main__':          #运行
  main()

参考:链接

11、使用PIL crop图片

from PIL import Image
import matplotlib.pyplot as plt

plt.figure()
img = Image.open('pic/1.png')
# 0:与左边界的距离, 10:与上边界的距离,
# img.size[0] / 3:还是与左边界的距离, img.size[1] / 4:还是与上边界的距离
img_new = img.crop((0, 10, img.size[0] / 3, img.size[1] / 4))

plt.subplot(1,2,1)
plt.imshow(img)
plt.subplot(1,2,2)
plt.imshow(img_new)
plt.show()

参考:链接

12、PIL库中Image.new方法和paste方法

参考:链接1,可去除白色的paste参考:链接2

13、opencv cv2.LUT()

代码:

import cv2
import numpy as np
# img=np.array(([[[1,2,3],[1,2,3],[1,2,3]],[[1,2,3],[1,2,3],[1,2,3]]])).astype(np.uint8)
# img=np.array(([[1,2,3,4,5,6]])).astype(np.uint8)
img=np.array([1,2,3,4,5,6]).astype(np.uint8)
print(img.shape)	# (6,)
print(img.dtype)	# uint8
gamma=0.8
# 映射表必须为0-255(改成其他会报错)
gamma_table = [np.power(x / 255.0, gamma) * 255.0 for x in range(256)]
# numpy数组默认数据类型为int32,需要将数据类型转换成opencv图像适合使用的无符号8位整型uint8,否则会报错
gamma_table = np.round(np.array(gamma_table)).astype(np.uint8)
print(gamma_table)
img_gamma = cv2.LUT(img, gamma_table)
print(img_gamma)

输出:

gamma_table:
[ 0 3 5 7 9 11 13 14 16 18 19 21 22 24 25 26 28 29
31 32 33 35 36 37 39 40 41 42 44 45 46 47 48 50 51 52
53 54 56 57 58 59 60 61 63 64 65 66 67 68 69 70 71 73
74 75 76 77 78 79 80 81 82 83 84 85 86 88 89 90 91 92
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
111 112 113 114 115 116 117 118 119 120 121 122 123 123 124 125 126 127
128 129 130 131 132 133 134 135 136 137 138 139 140 140 141 142 143 144
145 146 147 148 149 150 151 151 152 153 154 155 156 157 158 159 160 161
161 162 163 164 165 166 167 168 169 169 170 171 172 173 174 175 176 177
177 178 179 180 181 182 183 183 184 185 186 187 188 189 190 190 191 192
193 194 195 196 196 197 198 199 200 201 202 202 203 204 205 206 207 207
208 209 210 211 212 212 213 214 215 216 217 217 218 219 220 221 222 222
223 224 225 226 227 227 228 229 230 231 232 232 233 234 235 236 236 237
238 239 240 240 241 242 243 244 245 245 246 247 248 249 249 250 251 252
253 253 254 255]

img_gamma:
[[ 3]
[ 5]
[ 7]
[ 9]
[11]
[13]]

参考:链接

14、CV2打开图片与Image打开图片相互转换

代码:

#1.Image对象->cv2(np.adarray)

img = Image.open(path)

img_array = np.array(img)


#2.cv2(np.adarray)->Image对象

img = cv2.imread(path)

img_Image = Image.fromarray(np.uint8(img))

参考:链接1链接2

15、bug:【UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0x90 in position 207: illegal multibyte sequence】

有时候打开的文件里面有中文,就会报UncodeDecodeError:‘gbk’ codec can’t decode byte的错误。
解决办法,在打开文件句柄的时候,增加encoding='UTF-8’就可以了。

fd = open('fileName', 'r', encoding='UTF-8')

16、cv2.getPerspectiveTransform 透视变换

参考:链接1链接2,这个链接3链接4也不错,此链接5也不错

17、cv2.drawContours() 轮廓绘制

参考:链接

18、Image旋转图片

参考:链接1,这个链接2比较好

19、transforms.Compose()函数

参考:链接1

20、PIL图像处理之ImageFilter

参考:链接1

21、如何解决cv2和PIL保存图片失真问题

cv2保存图片不失真参考链接1,PIL保存图片时在后面加一个参数 quality 即可,代码如下,

form PIL import Image
img = Image.open("xxx.jpg")
img.save(img_name, quality=95)
form PIL import Image
img = Image.open("xxx.jpg")
img.save(img_name, quality=95)

参考:链接1

22、opencv如何保存中文路径图片

参考:链接1

23、opencv绘制多边形

绘制矩形
代码:

import cv2
import imutils

img = cv2.imread("img/COCO_train2014_000000031604.jpg")
# 在 imutils 中缩放会自动保持图片的宽高比,只需指定 weight 和 height 其中一个参数,就会根据图片原比例自动计算出另一个
img = imutils.resize(img, width=500)
# showCrosshair:是否在矩形框里画十字线,fromCenter:是否是从矩形框的中心开始画
roi = cv2.selectROI(windowName="roi", img=img, showCrosshair=False, fromCenter=False)
x, y, w, h = roi
print("rectangle coordinate:", roi)
cv2.rectangle(img=img, pt1=(x, y), pt2=(x + w, y + h), color=(0, 0, 255), thickness=2)
cv2.imshow("roi", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果:

rectangle coordinate: (47, 224, 187, 113)

在这里插入图片描述
绘制多边形

import cv2
import imutils
import numpy as np
import joblib

pts = []  # 用于存放点


# 统一的:mouse callback function
def draw_roi(event, x, y, flags, param):
    img2 = img.copy()

    if event == cv2.EVENT_LBUTTONDOWN:  # 左键点击,选择点
        pts.append((x, y))

    if event == cv2.EVENT_RBUTTONDOWN:  # 右键点击,取消最近一次选择的点
        pts.pop()

    if event == cv2.EVENT_MBUTTONDOWN:  # 中键绘制轮廓
        mask = np.zeros(img.shape, np.uint8)
        points = np.array(pts, np.int32)
        points = points.reshape((-1, 1, 2))
        # 画多边形,画多条线
        mask = cv2.polylines(mask, [points], True, (255, 255, 255), 2)
        # cv2.fillPoly填充的点矩阵放入[]中
        mask2 = cv2.fillPoly(mask.copy(), [points], (255, 255, 255))  # 用于求 ROI
        mask3 = cv2.fillPoly(mask.copy(), [points], (0, 255, 0))  # 用于 显示在桌面的图像
        # cv2.addWeighted:图像权重加法函数
        show_image = cv2.addWeighted(src1=img, alpha=0.8, src2=mask3, beta=0.2, gamma=0)

        cv2.imshow("mask", mask)
        cv2.imshow("mask2", mask2)
        cv2.imshow("mask3", mask3)
        cv2.imshow("show_img", show_image)
        # cv2.bitwise_and:图像的与运算
        ROI = cv2.bitwise_and(mask2, img)
        cv2.imshow("ROI", ROI)
        cv2.waitKey(0)

    if len(pts) > 0:
        # 将pts中的最后一点画出来
        cv2.circle(img2, pts[-1], 3, (0, 0, 255), -1)

    if len(pts) > 1:
        # 画线
        for i in range(len(pts) - 1):
            cv2.circle(img2, pts[i], 5, (0, 0, 255), -1)  # x ,y 为鼠标点击地方的坐标
            cv2.line(img=img2, pt1=pts[i], pt2=pts[i + 1], color=(255, 0, 0), thickness=2)

    cv2.imshow('image', img2)


# 创建图像与窗口并将窗口与回调函数绑定
img = cv2.imread("img/COCO_train2014_000000031604.jpg")
img = imutils.resize(img, width=500)
cv2.namedWindow('image')
cv2.setMouseCallback('image', draw_roi)
print("[INFO] 单击左键:选择点,单击右键:删除上一次选择的点,单击中键:确定ROI区域")
print("[INFO] 按‘S’确定选择区域并保存")
print("[INFO] 按 ESC 退出")

while True:
    key = cv2.waitKey(1) & 0xFF
    if key == 27:
        break
    if key == ord("s"):
        saved_data = {
            "ROI": pts
        }
        joblib.dump(value=saved_data, filename="config.pkl")
        print("[INFO] ROI坐标已保存到本地.")
        break
cv2.destroyAllWindows()

参考:
1、CSDN绘制多边形链接
2、imutils参数解释链接
3、cv2.selectROI用法、参数 、返回值的解读
4、其他CSDN绘制多边形链接1
5、其他CSDN绘制多边形链接2
6、其他CSDN绘制多边形链接2
7、cv2.polylines,cv2.fillPoly,cv2.fillConvexPoly 链接
8、cv2.bitwise_and()图像的与运算,
9、cv2.line(),cv2.circle()等

24、其他图片格式转JPG

r_imgs_path = r"C:\Users\ISSTECH\Desktop\排水_污口数据集\net"
w_imgs_path = r"C:\Users\ISSTECH\Desktop\排水_污口数据集\jpg"
for item01 in tqdm(os.listdir(r_imgs_path)):
    s_img_path = os.path.join(r_imgs_path, item01)
    im = Image.open(s_img_path)
    if im.mode == "RGBA":
        im.load()  # required for png.split()
        background = Image.new("RGB", im.size, (255, 255, 255))
        background.paste(im, mask=im.split()[3])
    save_name = os.path.join(w_imgs_path, item01.replace(item01.split(".")[-1], 'jpg'))
    # 此处会保存到源filename路径下
    try:
        im.save('{}'.format(save_name), 'JPEG')
    except Exception as e:
        print(s_img_path)

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值