如何解決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)

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

DMA在C 中是指DirectMemoryAccess,直接內存訪問技術,允許硬件設備直接與內存進行數據傳輸,不需要CPU干預。 1)DMA操作高度依賴於硬件設備和驅動程序,實現方式因係統而異。 2)直接訪問內存可能帶來安全風險,需確保代碼的正確性和安全性。 3)DMA可提高性能,但使用不當可能導致系統性能下降。通過實踐和學習,可以掌握DMA的使用技巧,在高速數據傳輸和實時信號處理等場景中發揮其最大效能。

在C 中處理高DPI顯示可以通過以下步驟實現:1)理解DPI和縮放,使用操作系統API獲取DPI信息並調整圖形輸出;2)處理跨平台兼容性,使用如SDL或Qt的跨平台圖形庫;3)進行性能優化,通過緩存、硬件加速和動態調整細節級別來提升性能;4)解決常見問題,如模糊文本和界面元素過小,通過正確應用DPI縮放來解決。

C 在實時操作系統(RTOS)編程中表現出色,提供了高效的執行效率和精確的時間管理。 1)C 通過直接操作硬件資源和高效的內存管理滿足RTOS的需求。 2)利用面向對象特性,C 可以設計靈活的任務調度系統。 3)C 支持高效的中斷處理,但需避免動態內存分配和異常處理以保證實時性。 4)模板編程和內聯函數有助於性能優化。 5)實際應用中,C 可用於實現高效的日誌系統。

在C 中測量線程性能可以使用標準庫中的計時工具、性能分析工具和自定義計時器。 1.使用庫測量執行時間。 2.使用gprof進行性能分析,步驟包括編譯時添加-pg選項、運行程序生成gmon.out文件、生成性能報告。 3.使用Valgrind的Callgrind模塊進行更詳細的分析,步驟包括運行程序生成callgrind.out文件、使用kcachegrind查看結果。 4.自定義計時器可靈活測量特定代碼段的執行時間。這些方法幫助全面了解線程性能,並優化代碼。

在MySQL中,添加字段使用ALTERTABLEtable_nameADDCOLUMNnew_columnVARCHAR(255)AFTERexisting_column,刪除字段使用ALTERTABLEtable_nameDROPCOLUMNcolumn_to_drop。添加字段時,需指定位置以優化查詢性能和數據結構;刪除字段前需確認操作不可逆;使用在線DDL、備份數據、測試環境和低負載時間段修改表結構是性能優化和最佳實踐。

交易所內置量化工具包括:1. Binance(幣安):提供Binance Futures量化模塊,低手續費,支持AI輔助交易。 2. OKX(歐易):支持多賬戶管理和智能訂單路由,提供機構級風控。獨立量化策略平台有:3. 3Commas:拖拽式策略生成器,適用於多平台對沖套利。 4. Quadency:專業級算法策略庫,支持自定義風險閾值。 5. Pionex:內置16 預設策略,低交易手續費。垂直領域工具包括:6. Cryptohopper:雲端量化平台,支持150 技術指標。 7. Bitsgap:

C 中使用字符串流的主要步驟和注意事項如下:1.創建輸出字符串流並轉換數據,如將整數轉換為字符串。 2.應用於復雜數據結構的序列化,如將vector轉換為字符串。 3.注意性能問題,避免在處理大量數據時頻繁使用字符串流,可考慮使用std::string的append方法。 4.注意內存管理,避免頻繁創建和銷毀字符串流對象,可以重用或使用std::stringstream。
