OpenCV 自学 之 图像处理基础

图像的基本表示方法

1.二值图像

  • 仅仅包含黑白两色
  • 图像划分为小方块,白色像素点为1,黑色像素点为0

binaryImage

 2.灰度图像

  • 采用了更多数值以体现不同颜色
  • 通常处理256个灰度级,以[0,255]表示,”255“为纯白色,”0“为纯黑色。
LED显示屏灰度等级和灰度原理
​​​灰度级

 3.彩色图像

  • 不同的色彩空间具有不同的表示方式,以常用的RGB色彩空间学习。
  • 在RGB色彩空间中,存在R(red,红色)通道、G(green,绿色)通道和B(blue,蓝色)通道。通道值为[0,255]之间。用三个色彩通道组合表示颜色
  • 一共256×256×256=16777216种颜色
  • 在OpenCV中,通道的顺序是B→G→R;RGB色彩空间的通道顺序则为R→G→B。

像素处理

1.二值图像及灰度图像

  • OpenCV中最小的数据类型是无符号的8位数,以0和255表示二值图像。
  • 一个OpenCV灰度图像是一个二维数组 

例子:Numpy生成8×8的数组,模拟黑色图像,访问、修改。

import cv2
import numpy as np

img = np.zeros((8,8), dtype=np.uint8)
print("img=\n", img)

cv2.imshow("one", img)
cv2.waitKey()
print("读取像素点img[0,3]=", img[0, 3])
img[0,3] = 255

print("修改后img=\n", img)
print("读取像素点img[0,3]=", img[0, 3])
cv2.imshow("two", img)
cv2.waitKey()
cv2.destroyAllWindows()

结果:

代码分析:

  • 使用函数zeros()生成8×8大小且值都为0的二维数组,数值类型是np.uint8。
  • img[0,3]访问img第0行第3列的像素点,序号都从0开始。

例子:读取灰度图像,访问、修改

import cv2
from lib import path        #无需理会

img = cv2.imread(path.get_graph_path("Image.jpg"), 0)
cv2.imshow("demo", img)

for i in range(10, 100):
    for j in range(80, 100):
        img[i, j] = 255
cv2.imshow("after", img)
cv2.waitKey()
cv2.destroyAllWindows()

结果:

2.彩色图像

RGB模式的彩色图像在读入OpenCV内进行处理时,会按照行方向一次读取该RGB图像的B通道,G通道,R通道的像素点,并将像素点以行为单位存储在ndarray的列中。例如,R行×C列的元素RGB图像,在OpenCV内以BGR模式的三维数组形式存储,

B G R
B G R
B G R
B G R
B G R
B G R
B G R

image[0, 0, 0]可以访问image的B通道内第0行第0列上的像素点

  • 第一个索引表示第0行
  • 第二个索引表示第0列
  • 第三个索引表示第0个颜色通道

例子:生成三维数组,观察三个通道值的变化

import cv2
import numpy as np

# ------------- Channel Blue -------------
blue = np.zeros((300, 300, 3), dtype=np.uint8)
blue[:, :, 0] = 255
print("blue=\n", blue)
cv2.imshow("blue", blue)
# ------------- Channel Green -------------
green = np.zeros((300, 300, 3), dtype=np.uint8)
green[:, :, 1] = 255
print("green=\n", green)
cv2.imshow("green", green)
# ------------- Channel Red -------------
red = np.zeros((300, 300, 3), dtype=np.uint8)
red[:, :, 2] = 255
print("red=\n", red)
cv2.imshow("red", red)
# ------------- Close Windows -------------
cv2.waitKey()
cv2.destroyAllWindows()

例子:

import cv2
import numpy as np

img = np.zeros((300, 300, 3), dtype=np.uint8)
img[:, 0:100, 0] = 255
img[:, 100:200, 1] = 255
img[:, 200:300, 2] = 255
cv2.imshow("img", img)
# ------------- Close Windows -------------
cv2.waitKey()
cv2.destroyAllWindows()

 

例子:numpy生成3D 数组。模拟BGR模式的彩色图像,访问、修改。

import numpy as np
img = np.zeros((2, 4, 3), dtype=np.uint8)
print("img=\n", img)
print("读取像素点img[0,3]", img[0, 3])
print("读取像素点img[1,2,3]", img[1, 2, 2])
img[0, 3] = 255
img[0, 0] = [66, 77, 88]
img[1, 1, 1] = 3
img[1, 2, 2] = 4
img[0, 2, 0] = 5
print("修改后 img\n", img)
print("读取修改后像素点 img[1,2,2]", img[1, 2, 2])

结果:

img=
 [[[0 0 0]
  [0 0 0]
  [0 0 0]
  [0 0 0]]

 [[0 0 0]
  [0 0 0]
  [0 0 0]
  [0 0 0]]]
读取像素点img[0,3] = [0 0 0]
读取像素点img[1,2,3] = 0


修改后 img=
 [[[ 66  77  88]
  [  0   0   0]
  [  5   0   0]
  [255 255 255]]

 [[  0   0   0]
  [  0   3   0]
  [  0   0   4]
  [  0   0   0]]]
读取修改后像素点 img[1,2,2] = 4
 

例子:读取一幅彩色图像,访问、修改。

import cv2
from lib import path

img = cv2.imread(path.get_graph_path("Image.jpg"))
cv2.imshow("img", img)
print("access img[0,0] : ", img[0, 0])
print("access img[0,0,0] : ", img[0, 0, 0])
print("access img[0,0,1] : ", img[0, 0, 1])
print("access img[0,0,2] : ", img[0, 0, 2])
print("access img[50,0] : ", img[50, 0])
print("access img[100,0] : ", img[100, 0])
# area 1
for i in range(0, 50):
    for j in range(0, 100):
        for k in range(0, 3):
            img[i, j, k] = 255  # white

for i in range(50, 100):
    for j in range(0, 100):
        img[i, j] = [128, 128, 128]  # grey

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

cv2.imshow("after", img)
print("after img[0,0] : ", img[0, 0])
print("after img[0,0,0] : ", img[0, 0, 0])
print("after img[0,0,1] : ", img[0, 0, 1])
print("after img[0,0,2] : ", img[0, 0, 2])
print("after img[50,0] : ", img[50, 0])
print("after img[100,0] : ", img[100, 0])
cv2.waitKey()
cv2.destroyAllWindows()

结果:

access img[0,0] :  [ 63 130 157]
access img[0,0,0] :  63
access img[0,0,1] :  130
access img[0,0,2] :  157
access img[50,0] :  [100 200 224]
access img[100,0] :  [189 254 255]
after img[0,0] :  [255 255 255]
after img[0,0,0] :  255
after img[0,0,1] :  255
after img[0,0,2] :  255
after img[50,0] :  [128 128 128]
after img[100,0] :  [0 0 0]

3.使用 numpy.array 访问像素

numpy.array提供了item()和itemset()函数来访问和修改像素点,这两个函数结果优化处理,比使用索引快得多。

1.二值图像和灰度图像

item() : 更加高效得访问像素点,语法格式为

item(行, 列)

itemset() : 修改像素值,语法格式为

itemset(索引值, 新值)

例子:

import numpy as np
img = np.random.randint(10, 99,size=[5, 5], dtype=np.uint8)
print("img=\n", img)
print("read pixel img.item(3,2)=", img.item(3, 2))
img.itemset((3, 2), 255)
print("wrote img=\n", img)
print("wrote pixel img.item(3,2)=", img.item(3, 2))

结果:

img=
 [[95 36 19 45 31]
 [91 48 54 30 64]
 [31 29 45 10 70]
 [47 28 63 70 43]
 [84 91 63 86 52]]
read pixel img.item(3,2)= 63
wrote img=
 [[ 95  36  19  45  31]
 [ 91  48  54  30  64]
 [ 31  29  45  10  70]
 [ 47  28 255  70  43]
 [ 84  91  63  86  52]]
wrote pixel img.item(3,2)= 255

例子:生成一个灰度图像,让其中像素值均为随机数。

import numpy as np
import cv2
img = np.random.randint(0, 255, size=[255, 255], dtype=np.uint8)
cv2.imshow("demo", img)
cv2.waitKey()
cv2.destroyAllWindows()

 结果:

例子:读取一个灰度图像,访问,修改。

import numpy as np
import cv2

img = np.random.randint(0, 255,size=[255,255],dtype=np.uint8)
print("Before (img.item(3,2):", img.item(3, 2))
img.itemset((3, 2), 255)
print("After (img.item(3,2):", img.item(3, 2))
cv2.imshow("before", img)
# area
for i in range(50, 100):
    for j in range(80,130):
        img.itemset((i, j), 255)

cv2.imshow("after", img)
cv2.waitKey()
cv2.destroyAllWindows()

结果:

Before (img.item(3,2): 13
After (img.item(3,2): 255

2.彩色图像

 item() : 更加高效得访问RGB图像像素点,语法格式为

item(行, 列, 通道)

itemset() : 修改RGB图像得像素值,语法格式为

itemset(三元组索引值, 新值)

例子:numpy随机数生成3D数组, 模拟RGB色彩空间图像,用item()和Itemset()访问和修改。

import numpy as np

img = np.random.randint(0, 255, size=(2, 4, 3), dtype=np.uint8)
print("img=\n", img)
print("img[1, 2, 0]=", img.item(1, 2, 0))
print("img[0, 2, 1]=", img.item(0, 2, 1))
print("img[1, 0, 2]=", img.item(1, 0, 2))
img.itemset((1, 2, 0), 255)
img.itemset((0, 2, 1), 255)
img.itemset((1, 0, 2), 255)
print("After:")
print("img[1, 2, 0]=", img.item(1, 2, 0))
print("img[0, 2, 1]=", img.item(0, 2, 1))
print("img[1, 0, 2]=", img.item(1, 0, 2))

结果:

img=
 [[[ 64 239 138]
  [122  64 107]
  [238  78  73]
  [130  91 117]]

 [[153 130  52]
  [191 173 161]
  [ 76 246 223]
  [167  10 241]]]
img[1, 2, 0]= 76
img[0, 2, 1]= 78
img[1, 0, 2]= 52
After:
img[1, 2, 0]= 255
img[0, 2, 1]= 255
img[1, 0, 2]= 255

例子:生成彩色图像,让其中像素值均为随机数。

import cv2
import numpy as np

img = np.random.randint(0, 255, size=[255, 255, 3], dtype=np.uint8)
cv2.imshow("demo", img)
cv2.waitKey()
cv2.destroyAllWindows()

结果:

 例子:读取一个灰度图像,访问,修改。

import cv2
import numpy as np
from lib import path

img = cv2.imread(path.get_graph_path("Image.jpg"))
cv2.imshow("demo", img)
print("读取像素点img[0, 0, 0]=", img[0, 0, 0])
print("读取像素点img[0, 0, 1]=", img[0, 0, 1])
print("读取像素点img[0, 0, 2]=", img[0, 0, 2])
for i in range(0, 50):
    for j in range(0, 100):
        for k in range(0, 3):
            img[i, j, k] = 255
cv2.imshow("after", img)
cv2.waitKey()
cv2.destroyAllWindows()
print("修改后像素点img[0, 0, 0]=", img[0, 0, 0])
print("修改后像素点img[0, 0, 1]=", img[0, 0, 1])
print("修改后像素点img[0, 0, 2]=", img[0, 0, 2])

结果:

读取像素点img[0, 0, 0]= 63
读取像素点img[0, 0, 1]= 130
读取像素点img[0, 0, 2]= 157
修改后像素点img[0, 0, 0]= 255
修改后像素点img[0, 0, 1]= 255
修改后像素点img[0, 0, 2]= 255 

4.感兴趣区域(ROI)

我们对图像感兴趣的某个特定区域成为感兴趣区域(Region of Interest, ROI)。在设定ROI后,就可以对该区域进行整体操作。例如,将A(ROI)赋值给B,可以将B赋值给C(ROI)。从而达到区域C复制区域A的目的。

例子:ROI为 img[200:400, 200:400]

import numpy as np
import cv2

img = np.zeros((1000, 1000), dtype=np.uint8)
cv2.imshow("demo_0", img)
img[200:400, 200:400] = 255
cv2.imshow("demo_1", img)
a = img[200:400, 200:400]
img[200:400, 600:800] = a
cv2.imshow("demo_2", img)
cv2.waitKey()
cv2.destroyAllWindows()

结果:

例子:获得lena脸部信息

from lib import path
import cv2

img = cv2.imread(path.get_graph_path("img.png"), cv2.IMREAD_UNCHANGED)  # cv2.IMREAD_UNCHANGED=-1,保持原格式不变
print()
face = img[65:270, 200:350]
cv2.imshow("original", img)
cv2.imshow("face", face)
cv2.waitKey()
cv2.destroyAllWindows()

 结果:

 例子:对脸部进行打码。

from lib import path
import numpy as np
import cv2

img = cv2.imread(path.get_graph_path("img.png"), cv2.IMREAD_UNCHANGED)  # cv2.IMREAD_UNCHANGED=-1,保持原格式不变
cv2.imshow("original", img)
face = np.random.randint(0, 256, (205, 150, 3))
img[65:270, 200:350] = face
cv2.imshow("result", img)
cv2.waitKey()
cv2.destroyAllWindows()

结果:

例子:讲ROI复制到其他图像内

from lib import path
import numpy as np
import cv2

lena = cv2.imread(path.get_graph_path("img.png"))   # 默认转为BGR图像
gold = cv2.imread(path.get_graph_path("Image.jpg"))
lena[0:100, 370:470] = gold[0:100, 0:100]
cv2.imshow("combined", lena)
cv2.waitKey()
cv2.destroyAllWindows()

 结果:

 

5.通道操作

在OpenCv,通道按照B→G→R顺序存储。

在图像处理过程中, 可以根据需要对通道进行拆分和合并。

通道拆分

1.通过索引拆分

b = img[:,:,0]
g = img[:,:,1]
r = img[:,:,2]

 例子:演示通道拆分及通道值改变对彩色图像的影响

import cv2
from lib import path

img = cv2.imread(path.get_graph_path("img.png"))
cv2.imshow("img", img)

b = img[:, :, 0]
g = img[:, :, 1]
r = img[:, :, 2]

cv2.imshow("b", b)
cv2.imshow("g", g)
cv2.imshow("r", r)

img[:, :, 0] = 0
cv2.imshow("imgb0", img)
img[:, :, 1] = 0
cv2.imshow("imgg0", img)
img[:, :, 2] = 0
cv2.imshow("imgr0", img)

cv2.waitKey()
cv2.destroyAllWindows()

2.通过函数拆分

b, g, r = cv2.split(img)
等价:
b = cv2.split(img)
g = cv2.split(img)
r = cv2.split(img)

例子:使用函数拆分

import cv2
from lib import path

img = cv2.imread(path.get_graph_path("img.png"))
b, g, r = cv2.split(img)
cv2.imshow("B", b)
cv2.imshow("G", g)
cv2.imshow("R", r)
cv2.waitKey()
cv2.destroyAllWindows()

 通道合并

通道合并是通道拆分的逆过程,通过合并通道可以将三个通道的灰度图像构成一幅彩色图像。

函数cv2.merge()

import cv2
from lib import path

img = cv2.imread(path.get_graph_path("img.png"))
b, g, r = cv2.split(img)
bgr = cv2.merge([b, g, r])
rgb = cv2.merge([r, g, b])
cv2.imshow("img", img)
cv2.imshow("bgr", bgr)
cv2.imshow("rgb", rgb)
cv2.waitKey()
cv2.destroyAllWindows()

 6.获取图像属性

属性:

  • shape:彩色图像(行,列,通道),二值图像或灰度图像(行,列)
  • size:返回图像的像素数目。像素数目=行×列×通道
  • dtype:返回图像的数据类型

例子:观察图像的常用属性

import cv2
from lib import path

gray = cv2.imread(path.get_graph_path("img.png"), 0)
color = cv2.imread(path.get_graph_path("img.png"))
print("Gray attribute:")
print("shape:", gray.shape)
print("size:", gray.size)
print("dtype:", gray.dtype)

print("\nColor attribute:")
print("shape:", color.shape)
print("size:", color.size)
print("dtype:", color.dtype)

Gray attribute:
shape: (373, 497)
size: 185381
dtype: uint8

Color attribute:
shape: (373, 497, 3)
size: 556143
dtype: uint8

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值