目录
一.图像的信息
1.取、改像素点信息
①取、改一个区域的信息
②取、改一个点的信息
2.取图像的信息
二.边界填充
三.图片运算
1.图片加法
2.图片的加权混合
按教程上的说法,对于不同的类型有不同的取法。比如如果要取一个区域,那么直接用元组选择就行,如果要单独取一个像素点加遍历的话,用Numpy提供的函数会更快。
对于取一个区域的信息,我们肯定用像素框选择就行了,比如这样
import cv2
img = cv2.imread('test.jpg',1)
roi = img[10:500,10:500]
print(roi)
对于一个区域的修改的话,也可以这样,比如
import cv2
img=cv2.imread('test.jpg')
ball=img[280:340,330:390]
img[273:333,100:160]=ball
img=cv2.imshow('test', img)
cv2.waitKey(0)
import cv2
import numpy as np
img = cv2.imread('test.jpg',1)
print(img.item(500,500,0))
img.itemset(500,500,0,255)
print(img.item(500,500,0))
---------out---------
228
255
注意:此处使用的item与itemset写入和读入的都是一个标量,也就是说,也许img[100,100]能读出[255,255,255],但用item就只能用img.item(100,100,0) 这样分三次读取。写入同理。
import cv2
img = cv2.imread('test.jpg',1)
print(img.shape, img.size, img.dtype)
-----out-----
(1090, 1090, 3) 3564300 uint8
.shape返回(长,宽,通道数)
.size返回图像的像素数目?(我不知道为什么,这个值≠图片的内存大小,也≠长×宽)
.dtype返回图像的数据类型
据说对卷积计算有用?那就看看吧。
核心代码就是
res = cv2.copyMakeBorder(图片,上,下,左,右,类型)
前五个参数: src 输入图像 top, bottom, left, right 对应边界的像素数目
后一个参数:
-cv2.BORDER_REFLECT 重复最边边上的一个像素,一种拉伸感 aaaaaa|abcdefgh|hhhhhhh
-cv2.BORDER_REFLECT 边界的景象,你边界值是多少,就复制多少的像素当镜像fedcba|abcde-fgh|hgfedcb
-cv2.BORDER_DEFAULT 边界镜像,和上面差不多(官方说有差距,我没看出来)gfedcb|abcdefgh|gfedcba
-cv2.BORDER_WRAP 不知道怎么说了, 就像这样: cdefgh|abcdefgh|abcdefg
-cv2.BORDER_CONSTANT "我这个参数,比较特别"。他后面还需要额外增加一个参数_颜色。像这样
res = cv2.copyMakeBorder(img,100,100,100,100,cv2.BORDER_CONSTANT,value = [255,255,255])
首先要知道这一点,对于图片的加减和算术加减有些不同。它有定义域啊(0≤x≤255),也就是说运算顺序不同,是可能造成不同的结果的。假设三个灰度点为A200,B250,C10。那么A+B-C=200+250-10=245,而A-C+B=200-10+250=255。所以是不同的。
import cv2
import numpy as np
x = np.uint8([250])
y = np.uint8([10])
print (cv2.add(x,y)) # 250+10 = 260 => 255
print (x+y) # 250+10 = 260 % 256 = 4
两种的加法的方法得值不一样,所以尽量使用cv2.add()
都是学过线性代数的人了(对不起,我没学过23333),对于不同大小的矩阵,他们是不能直接相加的。所以要相加的话,必须两张图片有同样的通道数与长宽。
那么两张不同大小的图片,我们如何相加呢?那就是只对同样大小的矩阵进行相加,像这样
import cv2
import numpy as np
img1 = cv2.imread('test.jpg')
img2 = cv2.imread('test2.jpg')
rows,cols,channels = img2.shape
img1[0:rows, 0:cols ] = img2
cv2.imshow('res',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
如果不想把img2放在左上角,那么加一个固定的偏移就行:
img1[x:rows+x,y:cols+y] = img2
书里的代码有问题,跑不通,我也没试成功。