四时宝库

程序员的知识宝库

前端使用openCV处理图片的基础(opencv图像)

前言

前文我们讲了openCV如何在前端应用。
本文主要根据官方文档的Core Operations部分,带大家了解OpenCV图片处理时需要的一些基础知识,比如mat数据类型的操作,绘制形状等等。

获取图片属性

let src = cv.imread('imageUpload');
console.log('image width: ' + src.cols + '\n' +
            'image height: ' + src.rows + '\n' +
            'image size: ' + src.size().width + '*' + src.size().height + '\n' +
            'image depth: ' + src.depth() + '\n' +
            'image channels ' + src.channels() + '\n' +
            'image type: ' + src.type() + '\n');

比如上面这张图的属性打印出来就是:

image width: 600
image height: 473
image size: 600*473
image depth: 0
image channels 4
image type: 24

Mat

构造Mat

创建Mat实例时,可以传入size, type或者rows, cols, type,一般用默认构造方式:

let mat = new cv.Mat();

或者用数组来构建:

// 比如: let mat = cv.matFromArray(2, 2, cv.CV_8UC1, [1, 2, 3, 4]);
let mat = cv.matFromArray(rows, cols, type, array);

或者用imgData:

let ctx = canvas.getContext("2d");
let imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
let mat = cv.matFromImageData(imgData);

另外,还有3个静态函数:

// 1. 创建一个全是0的Mat
let mat = cv.Mat.zeros(rows, cols, type);
// 2. 创建一个全是1的Mat
let mat = cv.Mat.ones(rows, cols, type);
// 3. 创建一个单位矩阵的Mat
let mat = cv.Mat.eye(rows, cols, type);

注意:Mat实例一定记得要及时删除。

复制Mat

有2种复制方法:

// 1. Clone
let dst = src.clone();
// 2. CopyTo
src.copyTo(dst, mask);

转换Mat类型

src.convertTo(dst, rtype)
rtype代表期望的输出矩阵类型,或者说是深度,因为通道的数量与输入相同;如果rtype为负,输出矩阵的类型将与输入矩阵的相同。

读写像素

data

首先,需要了解不同的Data属性在不同语言中的type之间的关系:

通过data获取像素:


let row = 3, col = 4;
let src = cv.imread("canvasInput");
if (src.isContinuous()) {
    let index = row * src.cols * src.channels() + col * src.channels()
    let R = src.data[index];
    let G = src.data[index + 1];
    let B = src.data[index + 2];
    let A = src.data[index + 3];
}

注意:data操作只对连续的Mat有效,使用前应该用isContinuous函数检查。

at

通过at获取像素:

let row = 3, col = 4;
let src = cv.imread("canvasInput");
let colIndex = col * src.channels()
let R = src.ucharAt(row, colIndex);
let G = src.ucharAt(row, colIndex + 1);
let B = src.ucharAt(row, colIndex + 2);
let A = src.ucharAt(row, colIndex + 3);

注意:at操作只能读,不能写。

ptr

mat.ucharPtr(k)获取mat的第k行,mat.ucharPtr(i, j)获取mat的第i行第j列。

let row = 3, col = 4;
let src = cv.imread("canvasInput");
let pixel = src.ucharPtr(row, col);
let R = pixel[0];
let G = pixel[1];
let B = pixel[2];
let A = pixel[3];

颜色通道操作

有时我们需要单独操作图片的R/G/B通道,这时就需要对颜色通道进行分割,处理完毕后再合并。

let src = cv.imread("canvasInput");
let rgbaPlanes = new cv.MatVector();
// 分割
cv.split(src, rgbaPlanes);
// 获取R通道
let R = rgbaPlanes.get(0);
// 合并
cv.merge(rgbaPlanes, src);
src.delete(); rgbaPlanes.delete(); R.delete();

坐标点Point

有2种方式创建一个点:

let point = new cv.Point(x, y);
let point = {x: x, y: y};

像素点Scalar

let scalar = new cv.Scalar(R, G, B, Alpha);
let scalar = [R, G, B, Alpha];

尺寸Size

let size = new cv.Size(width, height);
let size = {width : width, height : height};

let circle = new cv.Circle(center, radius);
let circle = {center : center, radius : radius};

方形

let rect = new cv.Rect(x, y, width, height);
let rect = {x : x, y : y, width : width, height : height};

带旋转角度的方形:

let rotatedRect = new cv.RotatedRect(center, size, angle);
let rotatedRect = {center : center, size : size, angle : angle};

通过下面的方法获取方形的4个顶点:

let vertices = cv.RotatedRect.points(rotatedRect);
let point1 = vertices[0];
let point2 = vertices[1];
let point3 = vertices[2];
let point4 = vertices[3];

通过下面的方法获取方形的边界:

let boundingRect = cv.RotatedRect.boundingRect(rotatedRect);

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接