10-Day-Of-OpenCV

10-Day-Of-OpenCV,第1张

Image Basic Operations|Day 3
    • 1. 图像的基础 *** 作
      • 1.1 获取并修改像素值
      • 1.2 获取图像属性
      • 1.3 图像 ROI
      • 1.4 拆分及合并图像通道
      • 1.5 为图像扩边(填充)
    • 2. 图像上的算术运算
      • 2.1 图像加法
      • 2.3 图像混合
      • 2.3 按位运算

第一次学习OpenCV,在这里将学习如何利用OpenCV对图像进行基础 *** 作。


1. 图像的基础 *** 作

图像的基本 *** 作包括:
• 获取像素值并修改
• 获取图像的属性(信息)
• 图像的 ROI
• 图像通道的拆分及合并

1.1 获取并修改像素值

可以根据像素的行和列的坐标来获取它的像素值。


对 BGR 图像而言,返回值为 B,G,R 的值。


对灰度图像而言,则会返回他的灰度值。


import cv2
import numpy as np
# 首先读入一幅图像
img=cv2.imread('image.jpg')
px=img[100,100]
print px
blue=img[100,100,0]
print blue
## [57 63 68]
## 57

可以通过类似的方式修改像素值。


import cv2
import numpy as np
img=cv2.imread('image.jpg')
img[100,100]=[255,255,255]
print img[100,100]
## [255 255 255]

使用 Numpy 的 array.item()array.itemset() 获取每一个像素值。


使用 array.item() 分割所有 B,G,R 的值。


import cv2
import numpy as np
img=cv2.imread('image.jpg')
print img.item(10,10,2)
img.itemset((10,10,2),100)
print img.item(10,10,2)
## 50
## 100
1.2 获取图像属性

图像的属性包括:行,列,通道,图像数据类型,像素数目等。


img.shape 可以获取图像的形状。


他的返回值是一个包含行数,列数,通道数的元组,如果图像是灰度图,返回值仅有行数和列数。


img.size 可以返回图像的像素数目。


img.dtype 返回的是图像的数据类型。


import cv2
import numpy as np
img=cv2.imread('image.jpg')
print img.shape
## (280, 450, 3)
print img.size
## 378000
print img.dtype
## uint8
1.3 图像 ROI

ROI(图像感兴趣区域)
有时候我们需要对一幅图像的特定区域进行 *** 作。


ROI 也是使用 Numpy 索引来获得的。


我们选择图像中的某部分并把他拷贝到图像的其他区域。


import cv2
import numpy as np
img=cv2.imread('image.jpg')
px=img[280:340,330:390]
img[273:333,100:160]=px
1.4 拆分及合并图像通道

对 BGR 三个通道分别进行 *** 作,则需要把 BGR 拆分成单个通道。


也可以把独立通道的图片合并成一个 BGR 图像。


把独立通道的图片合并成一个 BGR 图像。


import cv2
import numpy as np
img=cv2.imread('image.jpg')
b,g,r=cv2.split(img)
img=cv2.merge(b,g,r)

或者

b=img[:,:,0]

使所有像素的红色通道值都为 0,直接使用 Numpy 索引。


import cv2
import numpy as np
img=cv2.imread('image.jpg')
img[:,:,2]=0
1.5 为图像扩边(填充)

在图像周围创建一个边。


可以使用 cv2.copyMakeBorder() 函数。


这个函数经常在卷积运算或 0 填充时被用到。



函数包含以下参数:
• src 输入图像
• top, bottom, left, right 对应边界的像素数目。



• borderType 要添加那种类型的边界,类型如下:

cv2.BORDER_CONSTANT 添加有颜色的常数值边界,还需要下一个参数(value)。


cv2.BORDER_REFLECT 边界元素的镜像。


比如: fedcba|abcdefgh|hgfedcb cv2.BORDER_REFLECT_101 or cv2.BORDER_DEFAULT 跟上面一样,但稍作改动。


例如: gfedcb|abcdefgh|gfedcba cv2.BORDER_REPLICATE 重复最后一个元素。


例如: aaaaaa|abcdefgh|hhhhhhh cv2.BORDER_WRAP 不知道怎么说了, 就像这样: cdefgh|abcdefgh|abcdefg

• value 边界颜色,如果边界的类型是 cv2.BORDER_CONSTANT

# -*- coding: utf-8 -*-
import cv2
import numpy as np
from matplotlib import pyplot as plt
BLUE=[255,0,0]
img1=cv2.imread('image.png')
replicate = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_WRAP)
constant= cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_CONSTANT,value=BLUE)
plt.subplot(231),plt.imshow(img1,'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(reflect101,'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()
# 由于是使用 matplotlib 绘制,所以交换 R 和 B 的位置,OpenCV 中是按 BGR,matplotlib 中是按 RGB 排列

2. 图像上的算术运算

图像上的算术运算,加法,减法,位运算等。


函数有:cv2.add()cv2.addWeighted() 等。


2.1 图像加法

使用函数 cv2.add() 将两幅图像进行加法运算。


可以直接使用 numpy,res=img1+img。


两幅图像的大小,类型必须一致,或者第二个图像可以使一个简单的标量值。



OpenCV 中的加法与 Numpy 的加法是有所不同的。


OpenCV 的加法是一种饱和 *** 作,而 Numpy 的加法是一种模 *** 作。


x = np.uint8([250])
y = np.uint8([10])
print cv2.add(x,y) # 250+10 = 260 => 255
[[255]]
print x+y # 250+10 = 260 % 256 = 4
[4]
2.3 图像混合

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



图像混合的计算公式如下:g (x) = (1 − α) f0 (x) + αf1 (x)。


通过修改 α 的值(0 → 1),可以实现混合。



函数 cv2.addWeighted() 可以按此公式(dst = α · img1 + β · img2 + γ)对图片进行混合 *** 作。



现在把两幅图混合在一起。


第一幅图的权重是 0.7,第二幅图的权重是 0.3。


这里 γ 的取值为 0。


# -*- coding: utf-8 -*-
import cv2
import numpy as np
img1=cv2.imread('img1.png')
img2=cv2.imread('img2.jpg')
dst=cv2.addWeighted(img1,0.7,img2,0.3,0)
cv2.imshow('dst',dst)
cv2.waitKey(0)
cv2.destroyAllWindow()
2.3 按位运算

按位 *** 作有:AND,OR,NOT,XOR 等。


可以提取图像非矩形 ROI 部分。



按位运算实现:

# -*- coding: utf-8 -*-
import cv2
import numpy as np
# 加载图像
img1 = cv2.imread('img1.jpg')
img2 = cv2.imread('img2.png')
# 把图像的某部分放在左上角,首先创建一个ROI
rows,cols,channels = img2.shape
roi = img1[0:rows, 0:cols ]
# 现在为图像创建一个mask 并创建它的反向mask
img2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(img2gray, 175, 255, cv2.THRESH_BINARY)
mask_inv = cv2.bitwise_not(mask)
# 现在在 ROI 中涂黑图像区域
# 取 roi 中与 mask 中不为零的值对应的像素的值,其他值为 0
# 注意这里必须有 mask=mask 或者 mask=mask_inv, 其中的 mask= 不能忽略
img1_bg = cv2.bitwise_and(roi,roi,mask = mask)
# 取 roi 中与 mask_inv 中不为零的值对应的像素的值,其他值为 0。


# 从徽标图像中只取徽标区域 img2_fg = cv2.bitwise_and(img2,img2,mask = mask_inv) # 把图像放在 ROI 和修改主图像 dst = cv2.add(img1_bg,img2_fg) img1[0:rows, 0:cols ] = dst cv2.imshow('res',img1) cv2.waitKey(0) cv2.destroyAllWindows()

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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存