changeImageElement.onclick = function () { // 图片处理 }
首先读取图片:
1
let src = cv.imread("imageUpload");
接着做一些预处理,先灰度:
1 2
let dst = new cv.Mat(); cv.cvtColor(src, dst, cv.COLOR_BGR2GRAY, 0); // 转灰度
再高斯模糊:
1
cv.GaussianBlur(dst, dst, new cv.Size(3, 3), 0); // 高斯模糊
再Canny检测边缘:
1
cv.Canny(dst, dst, 75, 200); // 边缘检测
检测出边缘后,通过findContours找出所有轮廓:
1 2 3
let contours = new cv.MatVector(); let hierarchy = new cv.Mat(); cv.findContours(dst, contours, hierarchy, cv.RETR_CCOMP, cv.CHAIN_APPROX_SIMPLE)
然后从所有轮廓中找到面积最大的闭合轮廓:
1 2 3 4 5 6 7 8
let index = 0, maxArea = 0; for (let i = 0; i < contours.size(); ++i) { let tempArea = Math.abs(cv.contourArea(contours.get(i))); if (tempArea > maxArea) { index = i; maxArea = tempArea; } }
如果把这个找到的轮廓显示出来,就是这样:
然后通过上面找到的轮廓进行多边形拟合,从而得到4个顶点:
1 2 3 4 5 6 7 8 9 10 11 12
const foundCours = contours.get(index); const arcL = cv.arcLength(foundCtrue); let tmp = new cv.Mat(); // 逼近多边形 cv.approxPolyDP(foundCours, tmp, 0.01 * arcL, true); let points = []; if (tmp.total() === 4) { const data32S = tmp.data32S; for (let i = 0, len = data32S.length / 2; i < len; i++) { points[i] = { x: data32S[i * 2], y: data32S[i * 2 + 1] }; } }