前端使用openCV处理图片的基础
2021-10-15
次访问
前言
前文我们讲了openCV如何在前端应用。
本文主要根据官方文档的Core Operations部分,带大家了解OpenCV图片处理时需要的一些基础知识,比如mat数据类型的操作,绘制形状等等。
获取图片属性
1 | let src = cv.imread('imageUpload'); |
比如上面这张图的属性打印出来就是:
1 | image width: 600 |
Mat
构造Mat
创建Mat实例时,可以传入size, type或者rows, cols, type,一般用默认构造方式:
1 | let mat = new cv.Mat(); |
或者用数组来构建:
1 | // 比如: let mat = cv.matFromArray(2, 2, cv.CV_8UC1, [1, 2, 3, 4]); |
或者用imgData:
1 | let ctx = canvas.getContext("2d"); |
另外,还有3个静态函数:
1 | // 1. 创建一个全是0的Mat |
Mat实例一定记得要及时删除
复制Mat
有2种复制方法:
1 | // 1. Clone |
转换Mat类型
src.convertTo(dst, rtype)
rtype代表期望的输出矩阵类型,或者说是深度,因为通道的数量与输入相同;如果rtype为负,输出矩阵的类型将与输入矩阵的相同。
读写像素
data
首先,需要了解不同的Data属性在不同语言中的type之间的关系:
Data属性 | C++ Type | JavaScript Typed Array | Mat Type |
---|---|---|---|
data | uchar | Uint8Array | CV_8U |
data8S | char | Int8Array | CV_8S |
data16U | ushort | Uint16Array | CV_16U |
data16S | short | Int16Array | CV_16S |
data32S | int | Int32Array | CV_32S |
data32F | float | Float32Array | CV_32F |
data64F | double | Float64Array | CV_64F |
通过data获取像素:
1 | let row = 3, col = 4; |
data操作只对连续的Mat有效,使用前应该用isContinuous函数检查。
at
Mat Type | At 操作 |
---|---|
CV_8U | ucharAt |
CV_8S | charAt |
CV_16U | ushortAt |
CV_16S | shortAt |
CV_32S | intAt |
CV_32F | floatAt |
CV_64F | doubleAt |
通过at获取像素:
1 | let row = 3, col = 4; |
at操作只能读,不能写。
ptr
Mat Type | Ptr 操作 | JavaScript Typed Array |
---|---|---|
CV_8U | ucharPtr | Uint8Array |
CV_8S | charPtr | Int8Array |
CV_16U | ushortPtr | Uint16Array |
CV_16S | shortPtr | Int16Array |
CV_32S | intPtr | Int32Array |
CV_32F | floatPtr | Float32Array |
CV_64F | doublePtr | Float64Array |
mat.ucharPtr(k)获取mat的第k行,mat.ucharPtr(i, j)获取mat的第i行第j列。
1 | let row = 3, col = 4; |
颜色通道操作
有时我们需要单独操作图片的R/G/B通道,这时就需要对颜色通道进行分割,处理完毕后再合并。
1 | let src = cv.imread("canvasInput"); |
坐标点Point
有2种方式创建一个点:
1 | let point = new cv.Point(x, y); |
像素点Scalar
1 | let scalar = new cv.Scalar(R, G, B, Alpha); |
尺寸Size
1 | let size = new cv.Size(width, height); |
圆
1 | let circle = new cv.Circle(center, radius); |
方形
1 | let rect = new cv.Rect(x, y, width, height); |
带旋转角度的方形:
1 | let rotatedRect = new cv.RotatedRect(center, size, angle); |
通过下面的方法获取方形的4个顶点:
1 | let vertices = cv.RotatedRect.points(rotatedRect); |
通过下面的方法获取方形的边界:
1 | let boundingRect = cv.RotatedRect.boundingRect(rotatedRect); |