【opencv_python学习之二】图像处理初识

0、背景介绍

在本篇文章中所有示例所处理的图片为下图0.1,图片名字为a.png。

图 0.1

下图0.2, 图片名字为b.png

图 0.2

下图0.3, 图片名字为c.png

图 0.3

1、获取并修改某点RGB值

1.1、获取某点RGB值

1.1.1、代码示例

代码: 1.1.py

import cv2
import numpy as np

# 读取图片a.png
img = cv2.imread('a.png')

# 获取(0,0)点的RGB值,并打印
px0 = img[0, 0]
print('坐标(0,0)点的BGR为: %s'%px0)
blue0 = img[0,0,0]
print('坐标(0,0)点的B值为: %s'%blue0)
green0 = img[0,0,1]
print('坐标(0,0)点的G值为: %s'%green0)
red0 = img[0,0,2]
print('坐标(0,0)点的R值为: %s\n'%red0)

# 获取(75,236)点的RGB值并打印
px100 = img[236,75]
print('坐标(75,236)点的BGR为: %s'%px100)
blue100 = img.item(236,75,0)
print('坐标(75,236)点的B值为: %s'%blue100)
green100 = img.item(236,75,1)
print('坐标(75,236)点的G值为: %s'%green100)
red100 = img.item(236,75,2)
print('坐标(75,236)点的R值为: %s'%red100)

1.1.2、运行结果

运行代码1.1.py结果为:

F:\QAQ\python\opencv>python 1.1.py
坐标(0,0)点的BGR为: [255 255 255]
坐标(0,0)点的B值为: 255
坐标(0,0)点的G值为: 255
坐标(0,0)点的R值为: 255

坐标(75,236)点的BGR为: [213 227 245]
坐标(75,236)点的B值为: 213
坐标(75,236)点的G值为: 227
坐标(75,236)点的R值为: 245

1.1.3、知识点

  • img[y, x, 0/1/2] 可以查看某个点的RGB值,其中0/1/2分别对应B/G/R。
  • img.item(y, x, 0/1/2) 可以查看某个点的RGB值,其中0/1/2分别对应B/G/R。
  • 推荐使用 img.item

1.2、修改某点RGB值

1.2.1、代码示例

代码: 1.2.py

import cv2
import numpy as np

# 读取图片a.png
img = cv2.imread('a.png')

# 显示原始图片
cv2.imshow('old picture', img)

for i in range(0, 100):
	for j in range(0, 100):
		img[i,j] = [255,255,255]

for i in range(100, 200):
	for j in range(100, 200):
		img.itemset((i,j,2), 255)		

# 显示替换过RGB的图片
cv2.imshow('new picture', img)
key = cv2.waitKey(0)
cv2.destroyAllWindows()

1.2.2、运行结果

运行代码1.2.py,结果如图1.2,可以看到我们左上角图片出现了空白和黄色

图 1.2

1.2.3、知识点

  • img[y, x] = [B, G, R] 可以设置某个点的RGB值。
  • img.itemset((y, x,0/1/2), BGR) 可以设置某个点的RGB值. 0/1/2分别对应B/G/R。
  • 推荐使用 img.itemset

2、获取图片属性

2.1、获取宽高和通道

2.1.1、代码示例

代码: 2.1.py

import cv2

img = cv2.imread('a.png')

print('图片竖直像素%s, 水平像素%s个, 通道有%s个'%
	(img.shape[0], img.shape[1], img.shape[2]))

2.1.2、运行结果

D:\work\python\opencv_python>python 2.1.p
图片竖直像素510, 水平像素445个, 通道有3个

使用Photoshop查看文档,如图2.1,和上面结果一致

![](http://git.oschina.net/diefrom/imgForMk/raw/master/opencv_python_base_deal_03.png) 图 2.1

2.1.3、知识点

  • img.shape 可以获取图片宽、高以及通道数。

2.2、获取像素个数

2.2.1、代码示例

代码: 2.2.py

import cv2

img = cv2.imread('a.png')

print('文件总共像素: %s 个'%img.size)

print('高(%s) * 宽(%s) * 通道数(%s) = %s'%(img.shape[0], img.shape[1], img.shape[2], 
	int(img.shape[0]) * int(img.shape[1]) * int(img.shape[2]) ))

2.2.2、运行结果

F:\QAQ\python\opencv>python 2.2.py
文件总共像素: 680850 个
高(510) * 宽(445) * 通道数(3) = 680850

2.2.3、知识点

  • img.size 可以获取文件总像素点。
    该值等于 水平像素个数*垂直像素个数*通道个数

2.3、获取图片的data type

2.3.1、代码示例

代码: 2.3.py

import cv2

img = cv2.imread('a.png')

print('图片date type 为: %s'%img.dtype)

2.3.2、运行结果

F:\QAQ\python\opencv>python 2.3.py
图片data type 为: uint8

2.3.3、知识点

  • img.dtype可以获取图片的data type。

  • 图片的data type在debug时是一个非常重要的数据。掌握好data type可以避免图像失真。

  • 关于所有data type和取值范围可以查看下表2.1。

Data type Range
uint8 0 to 255
uint16 0 to 65535
uint32 0 to 232
float -1 to 1 or 0 to 1
int8 -128 to 127
int16 -32768 to 32767
int32 -231 to 231 - 1
表 2.1

3、图像部分区域的获取和更改

3.1、截取某区域后复制到另一区域

3.1.1、代码示例

代码: 3.1.py

import cv2

img = cv2.imread('a.png')

ball = img[43:239, 231:418]
img[0:196, 0:187] = ball

cv2.imshow('img', img)
key = cv2.waitKey(0)
cv2.destroyAllWindows()

3.1.2、运行结果

图 3.1

3.1.3、知识点

  • ROI(Region Of Images) 可以用于人脸识别。

  • img[y1:y2, x1:x2] 可以获取图片的某个区域。

  • 使用 img[y1:y2, x1:x2] 可以将某个区域的图像复制到另一个区域去,比如例子中,将图片中的蝴蝶复制到左上角。这里需要注意的是,前面的参数是y轴范围,后面的参数是x轴范围。例子中的这个操作很像Photoshop中的仿制图章。

4、图像通道操作

4.1、调整某个通道的值

4.1.1、代码示例

代码: 4.1.py

import cv2

img = cv2.imread('a.png')

img[:,:,0] = 200

cv2.imshow('img', img)
key = cv2.waitKey(0)
cv2.destroyAllWindows()

代码: 4.2.py

import cv2
import numpy as np

img = cv2.imread('a.png')

b, g, r = cv2.split(img)
b[:,:] = 200
img = cv2.merge((b, g, r))

cv2.imshow('img', img)
key = cv2.waitKey(0)
cv2.destroyAllWindows()

4.1.2、运行结果

分别运行4.1.py4.2.py,结果都如下图4.1

图 4.1

4.1.3、知识点

  • img[:, :, 0/1/2] 可以修改某个通道的值,其中0/1/2分别对应B/G/R。
  • 在第一节我们知道 img[y, x, 0/1/2] 可以设置某个点的RGB,那么设置全部点就是设置整个通道,即 img[:, :, 0/1/2]
  • cv2.merge((b, g, r)) 可以修改图像的通道值。其中b/g/r的范围是0-255。
  • 对于 img[:, :, 0/1/2]cv2.merge((b, g, r)) 相当于Photoshop中修改某个通道的色阶,如图4.1。
  • 推荐使用img[:, :, 0/1/2]

5、图片叠加

5.1、图片叠加计算原理

5.1.1、代码示例

代码: 5.1.py

import cv2
import numpy as np

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

print('x = %s, y = %s'%(x, y))
print('cv2.add(x, y) = %s'%cv2.add(x,y))
print('x+y = %s'%(x+y))

5.1.2、运行结果

F:\QAQ\python\opencv>python 5.1.py
x = [250], y = [10]
cv2.add(x, y) = [[255]]
x+y = [4]

5.1.3、知识点

在上面的例子中

cv2.add(x, y) = cv2.add([250], [10]) = 250 + 10 = 260

由于uint8的范围是[0, 255],所以cv2.add([250], [10])的最终值为255

x + y = [250] + [10] = ( 250 + 10 ) % 256 = 4

5.2、相同大小的图片叠加

5.2.1、代码示例

代码: 5.2.py

import cv2

img1 = cv2.imread('a.png')
img2 = cv2.imread('b.png')

dst = cv2.addWeighted(img1,0.7,img2,0.3,0)
cv2.imshow('dst',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

5.2.2、运行结果

图 5.1

5.2.3、知识点

  • addWeighted可以叠加两张图片,但是这两张图片必须宽高、通道数都一样。

  • addWeighted的计算公式为

公式 5.1

对于上面例子
img1(100,100)点的BGR为: [178 240 216]
img2(100,100)点的BGR为:[255 255 255]
合成图像(100,100)点的BGR为:[201 244 228]

对于坐标(100,100)的点,根据以上公式则可以得出

B: a * img1 + b * img2 + r = 0.7 * 178 + 0.3 * 255 + 0 = 201.1 = 201
G: a * img1 + b * img2 + r = 0.7 * 240 + 0.3 * 255 + 0 = 244.5 = 244
R: a * img1 + b * img2 + r = 0.7 * 216 + 0.3 * 255 + 0 = 227.7 = 228

5.3、不同大小的图片叠加

5.3.1 代码示例

import cv2

img1 = cv2.imread('a.png')
img2 = cv2.imread('c.png')


rows,cols,channels = img2.shape
roi = img1[0:rows, 0:cols ]
img1[0:rows, 0:cols ] = img2

cv2.imshow('res',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()

5.3.2 运行结果

图 5.2

5.3.3 知识点

  • 既然add相关操作都是要求shape值相同,那么就要换一种思路叠加图片。即可以将图片a.png的某个区域设置成图片c.png。

  • img[y1:y2, x1:x2] = img2可以叠加两张图片

参考
Basic Operations on Images
Image data types and what they mean
Arithmetic Operations on Images

posted @ 2017-09-26 15:55  白应非  阅读(912)  评论(0编辑  收藏  举报