10-Day-Of-OpenCV-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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值