如何解決OpenCV.js投影變換後結果為空白透明圖片的問題?
如何解決opencv.js投影變換結果為空白的透明圖片問題
在使用opencv.js進行圖像處理時,有時候會遇到投影變換後圖像結果為空白的透明圖片的問題。以下是我遇到的問題以及解決方法。
我在處理圖像時,代碼能夠成功識別出文檔的四個坐標,但到了投影變換這一步,得到的結果總是空白的透明圖片,並且沒有報錯。以下是我使用的投影變換部分代碼:
// 投影變換let srcquad = cv.matfromarray(4, 1, cv.cv_32fc2, points.flat()); let dstquad = cv.matfromarray(4, 1, cv.cv_32fc2, [0, 0, img.cols, 0, img.cols, img.rows, 0, img.rows]); let transmtx = cv.getperspectivetransform(srcquad, dstquad); let target = new cv.mat(); cv.warpperspective(img, target, transmtx, new cv.size(img.cols, img.rows)); // 顯示結果cv.imshow(canvas, target);
為了解決這個問題,我進行了以下改進:
- 設置canvas 大小:在圖像加載完成後,即在imgelement.onload 函數中,設置canvas 的寬度和高度與圖像的尺寸一致。
- 添加錯誤處理:在圖像加載失敗時,即在imgelement.onerror 函數中,添加錯誤處理以捕獲圖像加載錯誤。
以下是改進後的完整代碼:
<meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>OpenCV.js Example</title> <script async src="https://docs.opencv.org/4.5.5/opencv.js" onload="onOpenCvReady();"></script> <canvas id="canvasOutput"></canvas> <script> function onOpenCvReady() { console.log("OpenCV.js加載完成."); processImage(); } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function processImage() { await sleep(3000); // 等待3 秒let imageUrl = "../archives/111.jpg"; let imgElement = new Image(); imgElement.src = imageUrl; var img; // 加載圖像imgElement.onload = function() { try { img = cv.imread(imgElement); if (img.empty()) { console.error("Image could not be read."); return; } // 獲取canvas 元素並設置大小let canvas = document.getElementById('canvasOutput'); canvas.width = img.cols; canvas.height = img.rows; // 重置圖像大小let dsize = new cv.Size(img.cols, img.rows); let dst = new cv.Mat(); cv.resize(img, dst, dsize, 0, 0, cv.INTER_AREA); // 轉為灰度圖像console.log("轉換之前:", img); let gray = new cv.Mat(); // 創建一個新的Mat 對象來存灰度圖像cv.cvtColor(dst, gray, cv.COLOR_BGR2GRAY); // 使用適當的轉換console.log("轉換之後:", gray); // 高斯濾波cv.GaussianBlur(gray, gray, new cv.Size(11, 11), 0, 0); cv.imshow(canvas, gray); cv.Canny(gray, gray, 20, 50, 3); let contours = new cv.MatVector(); let hierarchy = new cv.Mat(); cv.findContours(gray, contours, hierarchy, cv.RETR_CCOMP, cv.CHAIN_APPROX_NONE); let index = 0, maxArea = 0; const area = img.cols * img.rows; for (let i = 0; i < contours.size(); i) { let tempArea = Math.abs(cv.contourArea(contours.get(i))); if (tempArea > maxArea && tempArea > 0.3 * area) { index = i; maxArea = tempArea; } } if (maxArea === 0) return; const foundContour = contours.get(index); const arcL = cv.arcLength(foundContour, true); let approx = new cv.Mat(); // 逼近多邊形cv.approxPolyDP(foundContour, approx, 0.01 * arcL, true); if (approx.total() === 4) { let points = []; const data32S = approx.data32S; for (let i = 0, len = data32S.length / 2; i < len; i ) { points[i] = {x: data32S[i * 2], y: data32S[i * 2 1]}; } console.log("檢測到四邊形點:", points); // 投影變換let srcQuad = cv.matFromArray(4, 1, cv.CV_32FC2, points.flat()); let dstQuad = cv.matFromArray(4, 1, cv.CV_32FC2, [0, 0, img.cols, 0, img.cols, img.rows, 0, img.rows]); let transmtx = cv.getPerspectiveTransform(srcQuad, dstQuad); let target = new cv.Mat(); cv.warpPerspective(img, target, transmtx, new cv.Size(img.cols, img.rows)); // 顯示結果cv.imshow(canvas, target); // 創建一個臨時的canvas 元素let tempCanvas = document.createElement('canvas'); tempCanvas.width = target.cols; tempCanvas.height = target.rows; let tempCtx = tempCanvas.getContext('2d'); // 將cv.Mat 轉換為ImageData let imageData = new ImageData(new Uint8ClampedArray(target.data), target.cols, target.rows); // 將ImageData 繪製到臨時的canvas 上tempCtx.putImageData(imageData, 0, 0); // 將canvas 生成Blob 對象tempCanvas.toBlob((blob) => { // 創建一個URL 對象let url = URL.createObjectURL(blob); // 創建一個a 元素並設置其屬性let a = document.createElement('a'); a.href = url; a.download = 'processed_image.png'; // 設置下載文件的名稱// 將a 元素添加到body 中document.body.appendChild(a); // 觸發點擊事件以開始下載a.click(); // 下載完成後移除a 元素document.body.removeChild(a); // 釋放URL 對象URL.revokeObjectURL(url); }, 'image/png'); // 釋放內存target.delete(); // 在這裡釋放target,否則會造成內存洩露} // 釋放內存img.delete(); dst.delete(); gray.delete(); // 釋放灰度圖像Mat contours.delete(); hierarchy.delete(); approx.delete(); foundContour.delete(); } catch (err) { console.error("圖像處理出現錯誤:", err); } } imgElement.onerror = function() { console.error("Image could not be loaded."); }; } </script>
通過上述改進,我成功解決了投影變換後結果為空白透明圖片的問題。希望這些改進對大家也有幫助。
以上是如何解決OpenCV.js投影變換後結果為空白透明圖片的問題?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

比特幣的價格在20,000到30,000美元之間。 1. 比特幣自2009年以來價格波動劇烈,2017年達到近20,000美元,2021年達到近60,000美元。 2. 價格受市場需求、供應量、宏觀經濟環境等因素影響。 3. 通過交易所、移動應用和網站可獲取實時價格。 4. 比特幣價格波動性大,受市場情緒和外部因素驅動。 5. 與傳統金融市場有一定關係,受全球股市、美元強弱等影響。 6. 長期趨勢看漲,但需謹慎評估風險。

靠谱的数字货币交易平台推荐:1. OKX,2. Binance,3. Coinbase,4. Kraken,5. Huobi,6. KuCoin,7. Bitfinex,8. Gemini,9. Bitstamp,10. Poloniex,这些平台均以其安全性、用户体验和多样化的功能著称,适合不同层次的用户进行数字货币交易

Binance、OKX、gate.io等十大數字貨幣交易所完善系統、高效多元化交易和嚴密安全措施嚴重推崇。

全球十大加密貨幣交易平台包括Binance、OKX、Gate.io、Coinbase、Kraken、Huobi Global、Bitfinex、Bittrex、KuCoin和Poloniex,均提供多種交易方式和強大的安全措施。

MeMebox 2.0通過創新架構和性能突破重新定義了加密資產管理。 1) 它解決了資產孤島、收益衰減和安全與便利悖論三大痛點。 2) 通過智能資產樞紐、動態風險管理和收益增強引擎,提升了跨鏈轉賬速度、平均收益率和安全事件響應速度。 3) 為用戶提供資產可視化、策略自動化和治理一體化,實現了用戶價值重構。 4) 通過生態協同和合規化創新,增強了平台的整體效能。 5) 未來將推出智能合約保險池、預測市場集成和AI驅動資產配置,繼續引領行業發展。

2025年全球十大加密貨幣交易所包括Binance、OKX、Gate.io、Coinbase、Kraken、Huobi、Bitfinex、KuCoin、Bittrex和Poloniex,均以高交易量和安全性著稱。

目前排名前十的虛擬幣交易所:1.幣安,2. OKX,3. Gate.io,4。幣庫,5。海妖,6。火幣全球站,7.拜比特,8.庫幣,9.比特幣,10。比特戳。

使用C 中的chrono庫可以讓你更加精確地控制時間和時間間隔,讓我們來探討一下這個庫的魅力所在吧。 C 的chrono庫是標準庫的一部分,它提供了一種現代化的方式來處理時間和時間間隔。對於那些曾經飽受time.h和ctime折磨的程序員來說,chrono無疑是一個福音。它不僅提高了代碼的可讀性和可維護性,還提供了更高的精度和靈活性。讓我們從基礎開始,chrono庫主要包括以下幾個關鍵組件:std::chrono::system_clock:表示系統時鐘,用於獲取當前時間。 std::chron
