opencv-python学习笔记——研0基础学习(持续更新)

opencv-python学习笔记——研0基础学习(持续更新),第1张

一、图像的介绍
  1. 图像以像素存储,若只有黑白颜色的三色图,为单通道,一个像素对应矩阵中的一个数字,数值为0到255。其中0表示最暗(黑色),255表示最亮(白色)。

    对于RGB模式的彩色图片,为三通道图,Red、Green、Blue三原色。一个像素块对应矩阵中的一个向量,分别表示三种颜色的比例。

    需要注意的是,由于历史遗留问题,opencv采用BGR模式,而不是RGB
二、图像读取保存 *** 作(cv2)
  1. 图像的读取:cv2.imread(img_path,flag)
    img_path: 图片的路径
    flag:
    cv2.IMREAD_COLOR,读取彩色图片,图片透明性会被忽略,为默认参数,也可以传入1
    cv2.IMREAD_GRAYSCALE,按灰度模式读取图像,也可以传入0
    cv2.IMREAD_UNCHANGED,读取图像,包括其alpha通道,也可以传入-1

  2. 图像的写入:cv2.imshow(window_name,img)
    window_name: 指定窗口的名字
    img:显示的图片对象
    可以指定多个窗口名称,显示多个图片

  3. 图像的保存:cv2.imwrite(img_path_name,img)
    img_path_name:保存的文件名
    img:文件对象

# 将导入包名另命名
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 1 读取图像
img = cv.imread('messi5.jpg',0)
# 2 显示图像
# 2.1 利用opencv展示图像
cv.imshow('image',img)
# 调用cv.waitKey()给图像绘制留下时间,否则窗口会出现无响应情况,并且图像无法显示出来。
k = cv.waitKey(0)
# 3 保存图像
cv.imwrite('messigray.png',img)



用cv2读取彩色图片通道顺序为B、G、R,PIL显示图片是R、G、B顺序,因此读出来图片颜色会改变,需要对图像通道进行调序。

未调整前

import cv2 as cv
import matplotlib.pyplot as plt
# 读取图像
img = cv.imread("E:\3.jpg")
# 将图片输出到屏幕
plt.imshow(img)
plt.show() 


调整后

import cv2 as cv
import matplotlib.pyplot as plt
# 读取图像
img = cv.imread("E:\3.jpg")
# 调整通道顺序
# split()将img分裂为三通道
b,g,r = cv.split(img)
# merge()将三通道合并
img = cv.merge([r,g,b])
# 将图片输出到屏幕
plt.imshow(img)
plt.show()  


加入了两行代码,如下

b,g,r = cv.split(img)
img = cv.merge([r,g,b])
三、图像像素获取和编辑
  1. 获取像素值,更改像素值
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
# 读取图像
img = Image.open("E:\3.jpg")
# 导入数组
img = np.array(img)
# 获取(100,100)处的像素值
pixel = img[100,100]
# 将[100,100]处的像素值设置为[0,0,0]
img[100,100]=[0,0,0]
# 将图片输出到屏幕
plt.imshow(img)
plt.show() 

更改前,[100,100]处像素值为[254,174,201]

更改后,[100,100]处的像素值为[0,0,0]

  1. 获取[100,100]处单通道像素值,并更改单通道像素值
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
# 读取图像
img = Image.open("E:\3.jpg")
# 导入数组
img = np.array(img)
# 获取(100,100)处的像素值
pixel = img[100,100]
#获取单通道像素值
b = img[100,100,0]
g = img[100,100,1]
r = img[100,100,2]
#更改red通道值
r = img[100,100,2]=0
# 将图片输出到屏幕
plt.imshow(img)
plt.show() 

更改后[100,100]处red像素值变为0.

  1. 使用函数获取单通道像素值:piexl = img.item(x,y,i)
    x表示横坐标,y表示纵坐标,i表示从左到右第几个元素。
    此处i可选用0,1,2.从左到右分别为b通道,g通道,r通道
  2. 使用函数设置单通道像素值:img.itemset((x,y,i),num)
    x,y,i同上。num自0~255取值,表示rgb颜色数值。
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
# 读取图像
img = Image.open("E:\3.jpg")
# 导入数组
img = np.array(img)
# 获取(100,100)处的像素值
pixel = img[100,100]
# 通过img.item() *** 作,可以直接定位到对应的区域。
# 即获取[100,100]处的第1个元素
piexl = img.item(100,100,0)
# itemset((x, y), z) 中的(x,y)代表的就是矩阵中元素位置,‘z’为该元素的值
img.itemset((100,100,0),99)
# 将图片输出到屏幕
plt.imshow(img)
plt.show()

四、图片性质及截取
  1. List item
    输出图片宽,长,通道数
import numpy as np
from PIL import Image
# 读取图像
img = Image.open("E:\3.jpg")
# 导入数组
img = np.array(img)
print(img.shape)

此处表示图片为宽500(rows),长500(cols),3通道(channels)

  1. 输出所有像素数
import numpy as np
from PIL import Image
# 读取图像
img = Image.open("E:\3.jpg")
# 导入数组
img = np.array(img)
print(img.size)

此处表示5005003=750000

  1. 输出图片数字类型
import numpy as np
from PIL import Image
# 读取图像
img = Image.open("E:\3.jpg")
# 导入数组
img = np.array(img)
print(img.dtype)

  1. ROI截取
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
# 读取图像
img = Image.open("E:\3.jpg")
# 导入数组
img = np.array(img)
#截取100行到200行,300列到400列
roi = img[100:200,300:400]
#将截取的区域roi移动到该区域
img[50:150,200:300] = roi
# 将图片输出到屏幕
plt.imshow(img)
plt.show()

原图

移动完

截取通道

import numpy as np
from PIL import Image
import cv2 as cv
import matplotlib.pyplot as plt
# 读取图像
img = Image.open("E:\3.jpg")
# 导入数组
img = np.array(img)
# 截取整个蓝色通道
b = img[:,:,0]
# 截取三个通道
b,g,r = cv.split(img)
# 按照rgb重新组合
img = cv.merge((r,g,b))
# 将图片输出到屏幕
plt.imshow(img)
plt.show()

五、添加边界
  1. cv2.copyMakeBorder()
    参数:
    img:图像对象
    top,bottom,left,right: 上下左右边界宽度,单位为像素值
    borderType:
    cv2.BORDER_CONSTANT, 带颜色的边界,需要传入另外一个颜色值
    cv2.BORDER_REFLECT, 边缘元素的镜像反射做为边界
    cv2.BORDER_REFLECT_101/cv2.BORDER_DEFAULT
    cv2.BORDER_REPLICATE, 边缘元素的复制做为边界
    CV2.BORDER_WRAP
    value: borderType为cv2.BORDER_CONSTANT时,传入的边界颜色值,如[0,255,0]
六、图像的运算
  1. 像素算数运算
    cv2.add(img1,img2,mask:None,dtype:-1)
    相加的两个图片,应该有相同的大小和通道
    img1:图片对象1
    img2:图片对象2
    mask:None (掩膜,一般用灰度图做掩膜,img1和img2相加后,和掩膜与运算,从而达到掩盖部分区域的目的)
    dtype:-1
import numpy as np
from PIL import Image
import cv2 as cv
import matplotlib.pyplot as plt
# 读取图像
plt.rc("font", family='Microsoft YaHei')
img1 = Image.open("E:\3.jpg")
img2 = Image.open("E:\4.jpg")
img1 = np.array(img1)
img2 = np.array(img2)
# cv中的加法
img3 = cv.add(img1,img2)
# 直接相加
img4 = img1+img2
# 图像显示
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img3[:,:,::-1])
axes[0].set_title("cv中的加法")
axes[1].imshow(img4[:,:,::-1])
axes[1].set_title("直接相加")
plt.show()

  1. 混合
    这其实也是加法,但是不同的是两幅图像的权重不同,这就会给人一种混合或者透明的感觉。

    img3 = cv.addWeighted(img1,alpha,img2,beta,gamma,dtype)
    参数:
    img1:图片对象1
    alpha:img1的权重
    img2:图片对象2
    beta:img1的权重
    gamma:常量值,图像相加后再加上常量值
    dtype:返回图像的数据类型,默认为-1,和img1一样
    (img1alpha+img2beta+gamma)

import numpy as np
from PIL import Image
import cv2 as cv
import matplotlib.pyplot as plt

# 读取图像
plt.rc("font", family='Microsoft YaHei')
img1 = Image.open("E:\3.jpg")
img2 = Image.open("E:\4.jpg")
img1 = np.array(img1)
img2 = np.array(img2)

# 2 图像混合
img3 = cv.addWeighted(img1,0.7,img2,0.3,0)

# 3 图像显示
plt.figure(figsize=(8,8))
plt.imshow(img3[:,:,::-1])
plt.show()

  1. 图像位运算
    cv2.btwise_and(): 与运算
    参数:
    img1:图片对象1
    img2:图片对象2
    mask:掩膜

    cv2.bitwise_or():或运算
    参数:
    img1:图片对象1
    img2:图片对象2
    mask:掩膜

    cv2.bitwise_not(): 非运算
    img1:图片对象1
    mask:掩膜

    cv2.bitwise_xor():异或运算,相同为1,不同为0(11=0,10=1)
    img1:图片对象1
    img2:图片对象2
    mask:掩膜

如何得到下方的效果:(接下来讲解步骤,详细代码请下滑)

第一步,截取 *** 作区域

img1 = cv.imread(r"E:.jpg")
# 读取前景的行数与列数
rows,cols = img1.shape[0:2]
#读取背景
img2 = cv.imread(r"E:.jpg")
#roi中存放的为背景分割出的与前景同行同列大小的图片,从[0,0]开始
roi = img2[0:rows,0:cols]


第二步,使用cv2.cvtColor()函数将图片转成灰度图

#是RGB到gray进行颜色转换
img1_gray = cv.cvtColor(img1,cv.COLOR_BGR2GRAY)


第三步,使用二值化函数cv2.threshold()将灰度图二值化

图像的二值化,就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的只有黑和白的视觉效果。
把大于某个临界灰度值的像素灰度设为灰度极大值,把小于这个值的像素灰度设为灰度极小值,从而实现二值化。
如此处阈值为200,即小于200设置为0,大于200设置为255

#threshold()函数形式:retval,dst = cv2.threshold(src,thresh,maxval,type)
#retval:阈值(临界值)、dst:处理后的图像、src:需要处理的图像、thresh:阈值
#maxval:最大像素值、type:阈值分割类型
ret,img1_thres = cv.threshold(img1_gray,200,255,cv.THRESH_BINARY)


第四步,使用“非” *** 作函数cv2.bitwise_not()将上图颠倒黑白:

img1_thres_inv = cv.bitwise_not(img1_thres)


第五步,使用“与” *** 作函数cv2.bitwise_and()对图像掩膜(遮挡)

# 对 *** 作区域掩膜
roi_bg = cv.add(roi,roi,mask=img1_thres_inv) 

#对img1掩膜
#用灰度图做掩膜,img1与img1相加后,与淹没与运算可以达到掩盖部分区域的目的。去黑留白
img1_fg =cv.add(img1,img1,mask=img1_thres)

掩膜(mask):以图和掩膜的与运算为例:
原图中的每个像素和掩膜中的每个对应像素进行与运算。比如1 & 1 = 1;1 & 0 = 0;
比如一个3 * 3的图像与3 * 3的掩膜进行运算,得到的结果图像就是:

  1. List item

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/758917.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-01
下一篇 2022-05-01

发表评论

登录后才能评论

评论列表(0条)

保存