入门图像
源码
`
import cv2 as cv
import sys
img = cv.imread(cv.samples.findFile("starry_night.jpg"))
if img is None:
sys.exit("Could not read the image.")
cv.imshow("Display window", img)
k = cv.waitKey(0)
if k == ord("s"):
cv.imwrite("starry_night.png", img)
`
函数
cv.imread
img = cv.imread(filename, flags)
从磁盘读取图像,返回一个 NumPy 数组
filename: 图像路径
flags:读取方式
cv.IMREAD_COLOR # 默认,BGR
cv.IMREAD_GRAYSCALE # 灰度
cv.IMREAD_UNCHANGED # 原始(tif 常用)
返回
numpy.ndarray 或 None
cv.imshow
cv.imshow(window_name, image)
window_name:窗口名
image:Numpy数组
cv.waitKey
key = cv.waitKey(delay)
delay:等待时间,0=无限
返回:ASCII 整数值
cv.imwrite
保存图像
cv.imwrite(filename, image)
filename :输出路径+文件名
image:图像数组
返回:True/False
图像基础操作
代码1
numpy修改索引进而修改像素点
import numpy as np
import cv2 as cv
img = cv.imread("Weilk-5-6h.tif")
assert img is not None, "file could not be read, check with os.path.exists()"
px = img[100,100]
print(px)
blue = img[100,100,0]
print(blue)
img[100,100] = [250,4,5]
print(img[100,100])
代码2
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
BLUE = [255, 0, 0]
img1 = cv.imread('xiaohui.png')
assert img1 is not None, "file could not be read, check with os.path.exists()"
replicate = cv.copyMakeBorder(img1, 10, 100, 10, 10, cv.BORDER_REPLICATE)
reflect = cv.copyMakeBorder(img1, 10, 100, 10, 10, cv.BORDER_REFLECT)
reflect101 = cv.copyMakeBorder(img1, 100, 10, 10, 10, cv.BORDER_REFLECT_101)
wrap = cv.copyMakeBorder(img1, 10, 10, 100, 10, cv.BORDER_WRAP)
constant = cv.copyMakeBorder(img1, 10, 100, 10, 10, cv.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()
函数
cv.copyMakeBorder
给图像四周加边框(padding),用于边界处理/卷积/展示。
dst = cv.copyMakeBorder(src, top, bottom, left, right, borderType, value=None)
src:输入图像
top, bottom, left, right:四边扩展像素数
borderType:边界类型
value:仅当 BORDER_CONSTANT 时有效 (填充颜色、灰度值)
-
borderType
cv.BORDER_REPLICATE:复制边缘像素cv.BORDER_REFLECT:镜像反射cv.BORDER_REFLECT_101:镜像反射(不重复边界,常用于滤波)cv.BORDER_WRAP:周期延拓cv.BORDER_CONSTANT:常数填充(需要value)
输出:
det:新的图像数组
cv.namedWindow
创建可调整大小的窗口
cv.namedWindow("img", cv.WINDOW_NORMAL)
cv.WINDOW_AUTOSIZE:默认,不可拉伸
cv.WINDOW_NORMAL:可拉伸
cv.threshold
把灰度图按阈值变成二值图(或做其它阈值变换)。
ret, dst = cv.threshold(src, thresh, maxval, type)
src:输入图
thresh:阈值T
maxval:超过阈值赋值的值
type:与值类型
-
常用type
cv.THRESH_BINARY:>T → maxval,否则 0cv.THRESH_BINARY_INV:反过来cv.THRESH_TRUNC:>T → Tcv.THRESH_TOZERO:<=T → 0cv.THRESH_TOZERO_INV:反向cv.THRESH_OTSU:Otsu 自动阈值(通常和 BINARY 组合)
输出:
ret:实际使用的阈值
dst:输出二值图
mask = src > T
方法更加灵活
NumPy 索引
img[y, x]:第 y 行、第 x 列像素
彩色时返回 [B, G, R]
img[y, x, c]:通道 c(0=B,1=G,2=R)
img[y1:y2, x1:x2]:ROI 子图
img[mask] = value:按 mask 批量修改
图像的算数运算
Image Addition:cv.add vs numpy +
OpenCV cv.add:饱和加法(超过上限就截断到 255)
img1 = cv.imread('xiaohui.png') # 背景图
img2 = cv.imread('Weilk-5-6h.tif') # 要贴上去的logo
rows, cols, channels = img1.shape
img2 = img2[0:rows, 0:cols]
img3 = cv.add(img1,img2)
cv.imshow("1",img3)
cv.waitKey(0)
cv.addWeighted
cv.addWeighted = “带权重的图像加法”
dst = cv.addWeighted(src1, alpha, src2, beta, gamma)
输入:两张图象+两张图象的权重
img1 = cv.imread('xiaohui.png') # 背景图
img2 = cv.imread('Weilk-5-6h.tif') # 要贴上去的logo
rows, cols, channels = img1.shape
img2 = img2[0:rows, 0:cols]
img3 = cv.addWeighted(img1,0.1,img2,0.9,0)
cv.imshow("1",img3)
cv.waitKey(0)
Image Blending:cv.addWeighted(透明叠加/融合)
两张图尺寸要一样(H、W 必须一致)
类型要兼容(通常都 uint8 或都 float)
一般让:alpha + beta = 1(视觉上更自然)
dst = cv.addWeighted(img1, 0.7, img2, 0.3, 0)
Bitwise Operations:AND / OR / NOT / XOR)
- cv.bitwise_not
- cv.bitwise_and
Bitwise Operations:AND / OR / NOT / XOR) 逐像素取反(位运算 NOT)。对二值 mask 来说就是黑白互换。
cv.cvtColor
颜色空间转换(BGR↔GRAY↔HSV…)
dst = cv.cvtColor(src,code)
输入:
src:输入图像(数组)
code:转换类型
输出:转换后的图像