我正在为大学开发一个MERN Stack项目,用户可以上传汽车照片,我希望使用OpenCV来模糊车牌,因此我需要使用一个“haarcascades”文件来识别区域。以下是相关代码:
const handlePhotosChange = async (e) => { const { files } = e.target; const selectedPhotos = Array.from(files); for (const photo of selectedPhotos) { const img = new Image(); img.src = URL.createObjectURL(photo); await new Promise((resolve) => { img.onload = () => { resolve(); }; }); const mat = cv.imread(img); const gray = new cv.Mat(); cv.cvtColor(mat, gray, cv.COLOR_RGBA2GRAY); const licensePlateCascade = new cv.CascadeClassifier(); const cascadeLoaded = licensePlateCascade.load( "haarcascade_license_plate_rus_16stages.xml" ); console.log("1"); if (cascadeLoaded) { console.log("2"); const plates = new cv.RectVector(); const minSize = new cv.Size(30, 30); licensePlateCascade.detectMultiScale(gray, plates, 1.1, 3, 0, minSize); for (let i = 0; i < plates.size(); i++) { const plate = plates.get(i); const plateMat = gray.roi(plate); cv.GaussianBlur(plateMat, plateMat, new cv.Size(5, 5), 0); plateMat.delete(); } const blurredImg = new Image(); blurredImg.src = URL.createObjectURL( new Blob([cv.imencode(".jpg", mat)], { type: "image/jpeg" }) ); const blurredBlob = await fetch(blurredImg.src).then((res) => res.blob() ); selectedPhotos[selectedPhotos.indexOf(photo)] = blurredBlob; plates.delete(); } mat.delete(); gray.delete(); licensePlateCascade.delete(); } setPhotos(selectedPhotos); };
我特别在这一行遇到了问题:
const cascadeLoaded = licensePlateCascade.load( "haarcascade_license_plate_rus_16stages.xml" );
代码执行的瞬间,控制台出现了以下错误:
[ERROR:[email protected]] global persistence.cpp:531 open Can’t open file: ‘haarcascade_license_plate_rus_16stages.xml’ in read mode
我尝试过使用完整路径,使用GitHub的原始链接,将文件放入public目录,以及将代码和文件放入后端,但都没有成功。
预期行为:文件无错误地加载。
回答:
感谢@Christoph Rackwitz的评论,我找到了解决方案
你需要做的:
1- 从OpenCV的GitHub仓库获取utils.js。
2- 为了使其正常工作,你需要在其中添加这一行(使用你使用的opencv.js的相对路径)
import * as cv from "../opencv/opencv";
3- 将其导入到你想要使用haarcascade的组件中。
import Utils from "../assets/utils";
同时,确保也导入了opencv.js。
4- 接下来,你需要将你选择的haarcascade文件放入/public
目录中。
5- 将其赋值给一个变量:
const xmlURL = "haarcascade_xxxx_license_plate.xml";
6- 最后,我们将使用utils.js中的createFileFromUrl()
来加载我们的haarcascade文件:
utils.createFileFromUrl(xmlURL, xmlURL, () => { licensePlateCascade.load(xmlURL);
为了方便起见,这里是完整的函数:
const handleLicensePlateDetection = async (e) => {try { console.log("Starting license plate detection..."); // Clean up previous resources if necessary if (window.src) window.src.delete(); if (window.gray) window.gray.delete(); if (window.plates) window.plates.delete(); if (window.licensePlateCascade) window.licensePlateCascade.delete(); const file = e.target.files[0]; const reader = new FileReader(); reader.onload = async () => { console.log("Image loaded successfully."); const image = new Image(); image.src = reader.result; image.onload = async () => { console.log("Converting image to grayscale..."); const src = cv.imread(image); const gray = new cv.Mat(); cv.cvtColor(src, gray, cv.COLOR_RGBA2GRAY, 0); console.log("Loading Haar Cascade XML file..."); const licensePlateCascade = new cv.CascadeClassifier(); const xmlURL = "haarcascade_xxx_license_plate.xml"; // Path to the XML file utils.createFileFromUrl(xmlURL, xmlURL, () => { try { licensePlateCascade.load(xmlURL); console.log("Haar Cascade XML file loaded successfully."); console.log("Detecting license plates..."); const plates = new cv.RectVector(); const msize = new cv.Size(0, 0); licensePlateCascade.detectMultiScale( gray, plates, 1.1, 3, 0, msize, msize ); console.log("Applying Gaussian blur to detected plates..."); for (let i = 0; i < plates.size(); ++i) { try { const plate = plates.get(i); const roi = src.roi(plate); cv.GaussianBlur( roi, roi, new cv.Size(23, 23), 40, 40, cv.BORDER_DEFAULT ); roi.delete(); } catch (error) { console.error( "Error applying Gaussian blur to plate:", error ); } } console.log("Displaying the result..."); cv.imshow("canvas", src); // Clean up src.delete(); gray.delete(); plates.delete(); licensePlateCascade.delete(); } catch (error) { console.error("Error loading Haar Cascade XML file:", error); } }); }; }; reader.readAsDataURL(file);} catch (error) { console.error("Error initializing license plate detection:", error);} };
注意:我对“AI”这类东西还不太熟悉,需要AI的帮助,因此我对刚刚粘贴的内容大部分都不理解