1、需要
要用JS来实现魔法棒的性能,首先须要实现找到邻近色彩的像素点,再标识进去。
刚实现了找到了邻近根本的像素点的局部。
2、代码
是图像宰割中的泛洪算法在前端中的利用。
<!-- * @Author: ArdenZhao * @Date: 2022-01-18 14:09:54 * @LastEditors: Do not edit * @LastEditTime: 2022-02-08 19:02:01 * @FilePath: /magic_wand/demo/4、myFloodFillData.html--><!DOCTYPE html><html><head> <meta charset="utf-8"> <title>Hello OpenCV.js</title> <style> #imageSrc, #canvasOutput { width: 50%; height: auto; } </style></head><body> <h2>Hello OpenCV.js</h2> <p id="status">OpenCV.js is loading...</p> <div> <div class="inputoutput"> <img id="imageSrc" alt="No Image" /> <div class="caption">imageSrc</div> </div> <div class="inputoutput"> <canvas id="canvasOutput"></canvas> <div class="caption">canvasOutput</div> </div> </div> <script type="text/javascript"> //获取图片标签 let imgElement = document.getElementById('imageSrc'); //获取canvas标签 let canvasElement = document.getElementById('canvasOutput'); imgElement.src = 'https://t7.baidu.com/it/u=1595072465,3644073269&fm=193&f=GIF'; imgElement.crossOrigin = "Anonymous"; function init_image(self, image_file) { self.image = cv2.imdecode(np.fromfile(image_file, dtype = np.uint8), 1) self.image_raw = self.image.copy() // self.img_h, self.img_w = self.image.shape[0: 2] // 原图宽高 } let imageArr = []; // 2、获取图片的宽高 let imageWidth = 0 let imageHeight = 0 imgElement.onload = function () { imageWidth = imgElement.width imageHeight = imgElement.height }; //异步获取后显示失常 function onOpenCvReady() { console.log('[ cv ] >', cv) document.getElementById('status').innerHTML = 'OpenCV.js is ready.'; cv['onRuntimeInitialized'] = () => { // 1、获取图片的数据 let mat = cv.imread(imgElement); let arr = [] // 3、构建图片的二维数组 for (let i = 0; i < mat.data.length; i = i + 4) { arr.push(mat.data.slice(i, i + 4)); } for (let j = 0; j < arr.length; j = j + imageWidth) { imageArr.push(arr.slice(j, j + imageWidth)); } cv.imshow('canvasOutput', mat); mat.delete(); //避免内存透露 }; } // 4、获取到Canvas点击的坐标 canvasElement.addEventListener('click', (e) => { let clickPoint = getMousePos(canvasElement, e) let seedMark = myFloodFill(imageArr, 10, clickPoint) // 默认20-30左右,动静输出 }, false); function getMousePos(canvas, event) { var rect = canvas.getBoundingClientRect();//办法返回元素的大小及其绝对于视口的地位 var x = event.clientX - rect.left * (canvas.width / rect.width); var y = event.clientY - rect.top * (canvas.height / rect.height); return [Math.round(x), Math.round(y)]; } // 5、改写泛洪办法,取得返回的区域 function myFloodFill(image, thresh, seedpoint) { // 构建图片的二维数组 let seedMark = new Array(imageHeight).fill(0).map(() => new Array(imageWidth).fill(0)); // 四邻域 let p = 4 let connection = [[-1, 0], [0, 1], [1, 0], [0, -1]] let seeds = [[seedpoint[1], seedpoint[0]]] //竖直方向在前,程度方向在后 let interval = thresh while (seeds.length > 0) { // 栈顶元素出栈 // pt=(y,x),opencv中程度为x坐标,竖直为y坐标,seeds输出坐标为先竖直坐标,后程度坐标 let pt = seeds.shift(0) let Ra = image[pt[0]][pt[1]][0] let Ga = image[pt[0]][pt[1]][1] let Ba = image[pt[0]][pt[1]][2] for (let i = 0; i < p; i++) { let x = pt[1] + connection[i][0] let y = pt[0] + connection[i][1] // 检测边界点 if (x < 0 || x >= imageWidth || y < 0 || y >= imageHeight) { continue } let Rb = image[y][x][0] let Gb = image[y][x][1] let Bb = image[y][x][2] // 满足魔法点的条件 if (seedMark[y][x] == 0 && ((Ra - Rb) <= interval) && (Ga - Gb) <= interval && (Ba - Bb) <= interval) { // 将魔法点标记为已拜访 seedMark[y][x] = 1 // 将魔法点压入栈 seeds.push([y, x]) } } } return seedMark } // todo // 6、显示图像的遮层 </script> <script async src="https://docs.opencv.org/4.5.0/opencv.js" onload="onOpenCvReady();" type="text/javascript"></script></body></html>