python cv2 numpy 一 (图像的基础操作,图像算术运算)

一,图像的基础操作

1.1 获取并修改像素值

import cv2
import os


imagePath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath("."))),"123.bmp")

image = cv2.imread(imagePath)

px = image[100,100]
print(px)
image[100,100,2] = 100
px = image[100,100,2]
print(px)

print(image.item(10,10,2))
image.itemset((10,10,2),100)  #  更改像素值这种方法比使用上面的矩阵方式更快。
print(image.item(10,10,2))

print(image.shape)

print(image.size)

输出结果如下:

[0 0 0]
100
0
100
(732, 861, 3)
1890756

1.2 获取图像数据类型

import cv2
import os


imagePath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath("."))),"123.bmp")

image = cv2.imread(imagePath)

print(image.dtype) #返回图像数据类型

print(image.shape)  #返回行,列,通道组成的元祖
"""
#通用代码获取图像 H ,W ,不用管是彩色图像还是黑白图像
"""
imgH,imgW = image.shape[:2]

print(imgH,imgW)

print(image.size)  #返回图像的像素数目

输出结果如下:

uint8
(732, 861, 3)
732 861
1890756

1.3 图像ROI区域

import cv2
import os
import copy
from matplotlib import pyplot as plt


imagePath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath("."))),"123.bmp")

image = cv2.imread(imagePath)

imageTemp = copy.deepcopy(image)

ball = imageTemp[400:450,400:450]
imageTemp[400:450,610:660] = ball  #在宽度方向进行覆盖,注意切片的大小必须一样

plt.subplot(121),plt.imshow(image,'gray'),plt.title('ORIGINAL')
plt.subplot(122),plt.imshow(imageTemp,'gray'),plt.title('CHANGE')

plt.show()

输出结果如下:

1.4 拆分和合并图像通道

import cv2
import os
from matplotlib import pyplot as plt

imagePath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath("."))),"123.bmp")

image = cv2.imread(imagePath)
"""
 #拆分 图像的通道 ,非常耗时,能不使用最好不要使用。
 opencv 读出来的图像默认是按照 B G R 通道的排序
"""
B,G,R = cv2.split(image)

"""
#使用numpy 索引比 cv2.split 速度快
"""
B = image[:,:,0]
G = image[:,:,1]
R  = image[:,:,2]

imageTemp = cv2.merge((R,G,B)) # 合并图像通道
imageTemp1 = cv2.merge((G,B,R)) # 合并图像通道

plt.subplot(221),plt.imshow(image,'gray'),plt.title('ORIGINAL')
plt.subplot(222),plt.imshow(imageTemp,'gray'),plt.title('CHANGE')
plt.subplot(223),plt.imshow(imageTemp1,'gray'),plt.title('CHANGE1')

plt.show()

输出结果如下:

1.5  为图像扩充边界

import cv2
import os
from matplotlib import pyplot as plt

BLUE = [255,0,0]

imagePath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath("."))),"OpenCVLogo.PNG")

image = cv2.imread(imagePath)


replicate = cv2.copyMakeBorder(image,50,50,50,50,cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(image,50,50,50,50,cv2.BORDER_REFLECT)
reflect_101 = cv2.copyMakeBorder(image,50,50,50,50,cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(image,50,50,50,50,cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(image,50,50,50,50,cv2.BORDER_CONSTANT,value=BLUE)

plt.subplot(231),plt.imshow(image,'gray'),plt.title('ORIGINAL')
plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('REPLICATE')
plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('REFLECT')
plt.subplot(234),plt.imshow(reflect_101,'gray'),plt.title('REFLECT_101')
plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP')
plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT')
plt.show()

输出结果如下:

函数cv2.copyMakeBorder 介绍:

参考opencv 官方教程:Image Filtering — OpenCV 2.3.2 documentation

函数原型:

cv2.copyMakeBorder(src, top, bottom, left, right, borderType[, dst[, value]]) → dst

Parameters:
  • src – Source image.
  • dst – Destination image of the same type as src and the size Size(src.cols+left+right, src.rows+top+bottom) .
  • top –
  • bottom –
  • left –
  • right – Parameter specifying how many pixels in each direction from the source image rectangle to extrapolate. For example, top=1, bottom=1, left=1, right=1 mean that 1 pixel-wide border needs to be built.
  • borderType – Border type. See borderInterpolate() for details.
  • value – Border value if borderType==BORDER_CONSTANT .

borderType :
cv2.BORDER_CONSTANT    常数填充:|oooo|abcd|oooo|
cv2.BORDER_ISOLATED    使用黑色像素进行填充,同:cv2.BORDER_CONSTANT类型且value=0
cv2.BORDER_REFLECT    从外向内取图像边缘的像素填充:|dcba|abcd|dcba|
cv2.BORDER_REFLECT101    反射填充的另一种情况,跳过原图边上的一个像素值:|dcb|abcd|cba|
cv2.BORDER_REFLECT_101    同cv2.BORDER_REFLECT101
cv2.BORDER_DEFAULT    同cv2.BORDER_REFLECT101
cv2.BORDER_REPLICATE    复制图像最边上的像素进行填充:|aaaa|abcd|dddd|
cv2.BORDER_TRANSPARENT    这个类型在新的OpenCV4中已经被取消
cv2.BORDER_WRAP    在图像对侧从外向内取图像边缘的像素填充:|dcba|abcd|abcd|

二,图像算术运算

2.1 图像混合

import os
import numpy as np

# BLUE = [255,0,0]

imagePath1 = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath("."))),"OpenCVLogo.PNG")
imagePath2 = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath("."))),"123.bmp")

image1 = cv2.imread(imagePath1)
image2 = cv2.imread(imagePath2)
image2 = image2[50:image1.shape[0]+50,50:image1.shape[1]+50]  #剪切出大小一样的图片
dst = cv2.addWeighted(image1,0.3,image2,0.7,0)

cv2.imshow("123",dst)
cv2.waitKey()

2.2 图像加法运算

import cv2
import os
import numpy as np


x = np.uint8([250])
y = np.uint8([10])

print(cv2.add(x,y))  # 250+10 = 260 => 255  OpenCV 有处理不会溢出


print(x+y)     # 250+10 = 260 % 256 = 4  普通加法会溢出

"""
两幅图像加法最好使用OpenCV.add 方法 不会溢出
"""

结果如下:

[[255]]
[4]

2.3 按位运算

import cv2
import os
import numpy as np
from matplotlib import pyplot as plt

"""
这里包括的按位操作有:AND,OR,NOT,XOR 等
"""

imagePath2 = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath("."))),"OpenCVLogo.PNG")
imagePath1 = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath("."))),"123.bmp")

image1 = cv2.imread(imagePath1)
image2 = cv2.imread(imagePath2)

rows,cols,channels = image2.shape
roi = image1[0:rows,0:cols]

img2gray = cv2.cvtColor(image2,cv2.COLOR_BGR2GRAY)
ret,mask = cv2.threshold(img2gray,175,255,cv2.THRESH_BINARY)
mask_inv = cv2.bitwise_not(mask)

img1_bg = cv2.bitwise_and(roi,roi,mask = mask)

img2_bg = cv2.bitwise_and(image2,image2,mask= mask_inv)

dst = cv2.add(img1_bg,img2_bg)

image1[0:rows,0:cols] = dst


plt.subplot(231),plt.imshow(image1[0:rows,0:cols],'gray'),plt.title('ORIGINAL')
plt.subplot(232),plt.imshow(img2gray,'gray'),plt.title('img2gray')
plt.subplot(233),plt.imshow(mask,'gray'),plt.title('mask')
plt.subplot(234),plt.imshow(mask_inv,'gray'),plt.title('mask_inv')
plt.subplot(235),plt.imshow(img1_bg,'gray'),plt.title('img1_bg')
plt.subplot(236),plt.imshow(img2_bg,'gray'),plt.title('img2_bg')

plt.show()

结果如下:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

u无名人士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值