【halcon】set_part 實現平移和縮放 徹悟版

背景

之前寫了一篇關于set_part 的文章 ,確實也實現了平移和縮放。平移是對的,但是縮放其實有畸變。這個問題一直都困擾著我,知道昨天連續測試了好幾個小時,直到晚上11點終于完美解決。

坐標和高寬

坐標

再講set_part 之前,我們先理一下,坐標和高寬
平時,我們通常使用 X, Y 來描述一個二維的坐標系。坐標原點一般是左下角。
而在halcon中,我們通常是使用 row 和 column來描述。
row 對應的是 Y, (row是一行行的,是Y方向走向)
column對應的是X。(colunm是一列列的,是X方向走向)
坐標原點在左上角。

高寬

高: 是 row 之間的差值(Y方向)。
寬: 是 column 之間的差值(X方向)

set_part 是 Halcon 中用于修改顯示圖像部分的算子。該算子允許你定義要在窗口中顯示的圖像的感興趣區域(ROI),并可以根據需要進行縮放。下面我們詳細解讀 set_part 算子的用法及參數:

set_part 算子簡單說明

1. 名稱

set_part — 修改顯示的圖像部分。

2. 簽名

set_part( : : WindowHandle, Row1, Column1, Row2, Column2 : )

3. 描述

set_part 修改在窗口中顯示的圖像部分。參數 (Row1, Column1) 表示圖像部分的左上角,(Row2, Column2) 表示圖像部分的右下角。
如果只顯示圖像的一部分,該部分將被縮放到整個窗口大小。可以使用 set_part_style 設置縮放插值方法。get_part 可以返回顯示的圖像部分的值。

除了直接設置圖像部分外,還支持以下特殊模式:

  • Row1 = Column1 = Row2 = Column2 = -1:
    窗口大小被選擇為圖像部分,即不執行圖像縮放。

  • Row1, Column1 > -1Row2 = Column2 = -1:
    選擇最后顯示的圖像大小為圖像部分,即圖像可以完全顯示在窗口中。如果需要,圖像將被縮放。

4. 參數

  • WindowHandle (input_control) : 窗口句柄,類型為 integer

  • Row1 (input_control) : 所選圖像部分左上角的行坐標,類型為 integer。默認值為 0

  • Column1 (input_control) : 所選圖像部分左上角的列坐標,類型為 integer。默認值為 0

  • Row2 (input_control) : 所選圖像部分右下角的行坐標,類型為 integer。默認值為 -1。限制:Row2 >= Row1Row2 == -1

  • Column2 (input_control) : 所選圖像部分右下角的列坐標,類型為 integer。默認值為 -1。限制:Column2 >= Column1Column2 == -1

set_part 深度理解

從上面的說明,我們需要理解一點。set_part 的坐標參數,它的參考系是圖片坐標的原點就是圖片的左上角那個點! **圖片動原點就跟著在變化!**理解這一點至關重要。

其實,一開始困擾的我的就是這個問題,一開始我認為,坐標系應該是以窗口為基準的,因為他是不會動的。但其實坐標系是以圖片為基準的。坐標的原點就是圖片的左上角那個點

再有就是,圖片是顯示在窗口里的,那窗口的坐標系是什么樣子的呢?首先窗口本身有自己的坐標系,窗口的左上角那個點就是窗口的坐標原點。

是如何跟圖片的坐標系關聯的呢?很簡單,看圖片在哪!
如果圖片的原點(圖片的左上角那個點)在和窗口的左上角那個點重合。那么窗口的坐標系是和圖的坐標系重合的。

圖片的縮放

那現在理解一下:
set_part(WindowHandle, 0, 0, 100, 100)
這句話是說明意思?
用在窗口這個視野內,顯示圖片的一個部分,哪個部分?就是Rect(0, 0, 100, 100)這個部分。
更具體的理解就是:
將圖片(0,0)這個點放到,窗口的左上角!,將圖片100, 100這個點到窗口的右下角!仔細體會這個字!
扯,其實就是圖片放大的一種差值算法。

例子1:
如果,窗口的大小是100x100,圖片的大小也是 100x100。那其實圖片就剛剛好放到窗口之中。

例子2:
窗口的大小是100100,圖片的大小是 100100。
但此時我修改程序為: set_part(WindowHandle, 0, 0, 50, 50)
圖片(0,0)這個點被固定在窗口的左上角,同時圖片(50, 50) 這個點會被扯到窗口的右下角(100,100),圖片就被放大了一倍。也就是說窗口大小如果不變,看到圖片的區域越小,圖片就會被’扯’的越大.

畸變是如何產生的

如果窗口的大小是200*100,而圖片是是 50*50。
我還是這么寫set_part(WindowHandle, 0, 0, 100, 100)
這樣的畫會發送什么?
同樣,圖片(0,0)這個點被固定在窗口的左上角。圖片(100, 100)右下角,被扯到了窗口的右下角(200*100)。
此時,你會發現,圖片的寬是之前的4倍,而高是之前的兩倍.
這樣寬高的放大比例不同,導致圖像產生了畸變!
那要確保不發生畸變,就是要保證寬和高的放大比例相同即可!
如何扯?紅色是窗口,藍色是圖片
那怎么扯,可以保證,圖片不變型
很明顯,窗口的寬高比為2:1 = 2, 而圖片的寬高比為1:1 = 1
窗口的寬高比 > 圖片寬高比。
所以, 當圖片的寬高同時緩慢放大時,如果圖片的高已經和窗口的高一致時,此時應該停止放大了!
放大后
這樣,圖片寬和高都放大了一倍,為發送形變。那此時set_part應該輸入寫呢?

前情提要:窗口的大小是200*100,而圖片是是 50*50。

寫法為:set_part(WindowHandle, 0, 0, 50, 100)
在這里插入圖片描述

含義就是,圖片的左上角固定在圖片的窗口的左上角,當圖片的(50,100)
這個點,被扯到窗口的右下角(200,100)時停止!
這里,可能有人會說了,圖片就 50*50。 哪來的(50,100)?
這里就需要引入一個自定義概念(就是自己根據情景編造的):圖片的延生坐標。此時,你就想象圖片本身就在一個巨大的彈性巨好的畫布上。畫布就是圖片的延時。(50,100)雖然不在圖片上但是在這個畫布上。我們扯畫布,圖片也會跟著形變。
那,這個50, 100這個點是怎么計算來的呢?這個點有幾個個前提:

  1. 圖片不發生形變
  2. 圖片顯示完全的情況下,實現最大的放大倍數。

很明顯,對應上面這種情況,圖片的高可以頂格顯示,而寬度則需要留白。
所以:
set_part(WindowHandle, 0, 0, 50, ?)

高: 是 row 之間的差值(Y方向)。

所以圖片的右下角 row值,可以扯到窗口的底部(row的最大位置。)以到達高度頂格顯示的目的。
那最后一點怎么算?因為現在圖片高度拉滿,就是圖片的高度50,那么用50再乘以窗口的寬高比,得到就是的第四個坐標的位置。

另外一種情況
在這里插入圖片描述
圖片的寬高比,大于窗口的寬高比。
就是圖片的寬度可以頂格顯示,高度留白。
假設圖片的寬度是w,那么、column方向向拉滿:
set_part(WindowHandle, 0, 0, ?, w)
?怎么求? w 除以 窗口的寬高比

做個小結:
首先就是需要分類討論,窗口的寬高比和圖片的寬高比哪個更大?從而判斷
圖片的那一條邊可以頂格顯示,從而計算另一個坐標的位置。
具體程序如下:

//計算縮放比例
double winWHRatio = WindowWidth.D / WindowHeight.D;
double picWHRatio = imgw.D / imgh.D;double dispWidth;
double dispHeight;//設置整個圖像為顯示的部分
if (picWHRatio >= winWHRatio)
{dispHeight = imgw / winWHRatio / PosEnlarge;dispWidth = imgw / PosEnlarge; HOperatorSet.SetPart(HalconWindow, 0, 0, dispHeight, dispWidth);
}
else
{dispHeight = imgh.D / PosEnlarge;dispWidth = imgh.D * winWHRatio / PosEnlarge;var offseth = row - dispHeight / 2;var offsetw = column- dispWidth / 2;HOperatorSet.SetPart(HalconWindow, 0, 0, dispHeight, dispWidth);}

不發生畸變的任意倍數放大

上面是加了一個添加的放大,就是
圖片顯示完全的情況下,實現最大的放大倍數。
現在,我想任意倍速放大!怎么實現?

//計算縮放比例
double winWHRatio = WindowWidth / WindowHeight;
double picWHRatio = imgw / imgh;double dispWidth;
double dispHeight;//設置整個圖像為顯示的部分
if (picWHRatio >= winWHRatio)
{dispHeight = imgw / winWHRatio;dispWidth = imgw; HOperatorSet.SetPart(HalconWindow, 0, 0, dispHeight, dispWidth);
}
else
{dispHeight = imgh;dispWidth = imgh * winWHRatio;HOperatorSet.SetPart(HalconWindow, 0, 0, dispHeight, dispWidth);
}

不發生畸變的任意倍數放大

上面是加了一個添加的放大,就是
圖片顯示完全的情況下,實現最大的放大倍數
現在,我想任意倍速放大!怎么實現?
我們,現在就定義,圖片顯示完全的情況下,實現最大的放大倍數。時為圖像放大一個倍數!也就是自適應的做大化顯示為一倍!

那如果,我要放大PosEnlarge倍,代碼修改如下:

//計算縮放比例
double winWHRatio = WindowWidth / WindowHeight;
double picWHRatio = imgw / imgh;double dispWidth;
double dispHeight;//設置整個圖像為顯示的部分
if (picWHRatio >= winWHRatio)
{dispHeight = imgw / winWHRatio / PosEnlarge;dispWidth = imgw / PosEnlarge; HOperatorSet.SetPart(HalconWindow, 0, 0, dispHeight, dispWidth);
}
else
{dispHeight = imgh / PosEnlarge;dispWidth = imgh * winWHRatio / PosEnlarge;HOperatorSet.SetPart(HalconWindow, 0, 0, dispHeight, dispWidth);
}

改動不大,就是將之前的dispHeight 和 dispWidth 多除以了一個PosEnlarge!比如如果是放大兩邊就是 PosEnlarge = 2即可。
這是因為,窗口大小沒變(視口不變),但是顯示的區域變小,圖片被拉大。
這次,不會畸變的原因是,此時在原來的基礎上,同時寬高放大的一樣的比例,所以不會畸變。放大的中心是(0,0)

圖像的平移

SetPart 圖像的縮放就講完了,如何設置通過SetPart 進行平移?
在這里插入圖片描述
首先,我們之前圖片的原點和窗口左上角是重合的,此時沒有平移。
如果圖片向左上方平移(25,25),那么此時,窗口的左上角應該顯示的是圖片(25,25)這個點。那窗口的右下角的點應該隨之變化 (25,25)及 row,column都加25。 這樣顯示的圖片范圍就是不變的而保證圖片是僅僅發生平移,而沒有形變。
那公式就是:
SetPart(HWindow, offseth, offsetw, dispHeight + offseth, dispWidth + offsetw);

這樣,就能通過,offseth, offsetw 來控制 平移

平移加上縮放

現在,我有一個需求,我可以設定放大倍數,而且當我輸入一個點時,需要將這個點移動到屏幕的中間!
接下來直接給出最終的代碼:

    /// <summary>/// 將某個目標位置移動到中間/// </summary>public void MoveSm2Center(HObject img, HTuple row, HTuple column){HTuple win_Width, win_Height, win_Col, win_Row;HOperatorSet.GetWindowExtents(hSmart.HalconWindow, out win_Row, out win_Col, out win_Width, out win_Height);//獲取窗體大小規格HTuple WindowWidth = win_Width;HTuple WindowHeight = win_Height;HTuple imgw;HTuple imgh;HOperatorSet.GetImageSize(img, out imgw, out imgh);//計算縮放比例double winWHRatio = WindowWidth.D / WindowHeight.D;double picWHRatio = imgw.D / imgh.D;double dispWidth;double dispHeight;//設置整個圖像為顯示的部分if (picWHRatio >= winWHRatio){dispHeight = imgw / winWHRatio / GlobalData.Instance.saveInfo.PosEnlarge;dispWidth = imgw /  GlobalData.Instance.saveInfo.PosEnlarge; HOperatorSet.SetPart(hSmart.HalconWindow, 0, 0, dispHeight, dispWidth);}else{dispHeight = imgh.D / GlobalData.Instance.saveInfo.PosEnlarge;dispWidth = imgh.D * winWHRatio / GlobalData.Instance.saveInfo.PosEnlarge;//var offseth = row - imgw / 2;//var offsetw = column - imgh / 2; var offseth = row - dispHeight / 2;var offsetw = column- dispWidth / 2;HOperatorSet.SetPart(hSmart.HalconWindow, offseth, offsetw, dispHeight + offseth, dispWidth + offsetw);}}

其中: GlobalData.Instance.saveInfo.PosEnlarge 是被定義為一個全局的變量。控制放大倍數。
HTuple row, HTuple column 傳入指定的點。
這里需要主義的是:
//var offseth = row - imgw / 2;
//var offsetw = column - imgh / 2;

var offseth = row - dispHeight / 2;
var offsetw = column- dispWidth / 2;
為了移到,屏幕的中間,我用的是 dispHeight / 2 和 dispWidth / 2
而不是 圖片大小的一半,或是 窗口大小的一半。

這是應為,不管是圖片還是窗口,他們的一半是固定大小的。 而圖片是縮放了的。
dispHeight 和 dispWidth 是圖片縮放后的結果。

好了就到這里了!!!!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/14949.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/14949.shtml
英文地址,請注明出處:http://en.pswp.cn/web/14949.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

免費擼gpt-4o和各種大模型實用經驗分享

項目 Github: https://github.com/MartialBE/one-api 先貼兩張圖&#xff1a; 說明 免費擼AI大模型,各位可以對照下面我給出的大模型記錄表來填&#xff0c;key需要自己去拿&#xff0c;國內都需要手機號驗證&#xff0c;如果你不介意。另外我在自己的博客放出免費API給大家…

模型評價指標筆記:混淆矩陣+F1+PR曲線+mAP

評價指標 二分類評價指標 混淆矩陣 TP: 正確預測為了正樣本&#xff0c;原來也是正樣本 FN: 錯誤的預測為負樣本&#xff0c;原來是正樣本 (漏報&#xff0c;沒有找到正確匹配的數目) FP: 錯誤的預測為正樣本&#xff0c;原來是負樣本 (誤報&#xff0c;沒有的匹配不正確) TN…

CIM模型

CIM 是 Esri 制圖信息模型。 它是一個地圖內容規范,用于記錄在保存、讀取、引用或打開時如何永久保留描述不同項目組件的信息。 該規范以 JSON 表示,適用于 ArcGIS 應用程序和 API 中的地圖、場景、布局、圖層、符號和樣式。 CIM 不僅限于制圖設置。 要了解屬性的組織方式以及…

【Tools】SpringBoot工程中,對于時間屬性從后端返回到前端的格式問題

Catalog 時間屬性格式問題一、需求二、怎么使用 時間屬性格式問題 一、需求 對于表中時間字段&#xff0c;后端創建對應的實體類的時間屬性需要設定格式&#xff08;默認的格式不方便閱讀&#xff09;&#xff0c;再返回給前端。 二、怎么使用 導入jackson相關的坐標&#x…

Vue.js - Vue 的安裝 以及 常用的 Vue 指令 【0基礎向 Vue 基礎學習】

文章目錄 Vue 快速上手1、Vue.js 官網 & Vue.js 的獲取2、創建 Vue 實例&#xff0c;初始化渲染3、插值表達式 安裝 Vue 開發者工具&#xff1a;裝插件調試 Vue 應用Vue 指令1、v-show 指令2、v-if3、v-else & v-else-if4、v-onv-on 調用傳參 5、v-bindv-bind 對于樣式…

【算法】前綴和算法——和為k的子數組之和

題解&#xff1a;和為k的子數組之和(前綴和算法) 目錄 1.題目2.題解思路2.1前綴和 哈希表&#xff0c;算法步驟&#xff1a;2.2細節如下&#xff1a;2.3參考代碼&#xff1a; 3.總結及思考 1.題目 題目鏈接&#xff1a;LINK 2.題解思路 暴力求解自然不用多說&#xff0c;時…

【SQL】外連接 LEFT JOIN

目錄 一.內連接與外連接 1.內連接&#xff08;inner join&#xff09; 2.外連接&#xff08;outer join&#xff09; 二.兩表連接 1.我們先來試試看內連接&#xff1a; 2.我們再來試試外連接 三.單表外連接 四.總結 一.內連接與外連接 先得介紹內連接和外連接兩個概念&…

第199題|關于函數的周期性問題|函數強化訓練(六)|武忠祥老師每日一題 5月24日

解題思路&#xff1a;解這道題我們要用到下面這個結論 f(x)連續&#xff0c;以T為周期時&#xff0c;原函數以T為周期的充分必要條件是&#xff1a; (A) sin x顯然是以π為周期的&#xff0c;我們可以看到并不等于0,根據結論&#xff0c;A的原函數顯然不是周期函數。 (B) 的…

memmove使?和模擬實現

一&#xff1a;memmove的使? 這是memmove在庫里的定義&#xff0c;具體可在cplusplus.com查看 void * memmove ( void * destination, const void * source, size_t num ) ? 和memcpy的差別就是memmove函數處理的源內存塊和?標內存塊是可以重疊的。 ? 如果源空間和?標…

你以為的私域是真正的私域嘛??你的私域流量真的屬于你嘛?

大家好 我是一個軟件開發公司的產品經理 專注私域電商行業7年有余 您的私域流量是真正的屬于你自己嘛&#xff1f; 私域的定義 私域的界定&#xff1a;一個互聯網私有數據&#xff08;資產&#xff09;積蓄的載體。這個載體的數據權益私有&#xff0c;且具備用戶規則制定權…

Mysql 備份恢復 mysqldump與xtrabackup備份

1.1 備份的原因 備份是數據安全的最后一道防線&#xff0c;對于任何數據丟失的場景&#xff0c;備份雖然不一定能恢復百分之百的數據 (取決于備份周期)&#xff0c;但至少能將損失降到最低。衡量備份恢復有兩個重要的指標&#xff1a;恢復點目標(RPO) 和恢復時間目標(RTO)&…

數據庫常用命令(1)

DML 1.添加數據&#xff08;insert into&#xff09; insert into 表名 values (值1&#xff0c;值2....); 表示成功運行&#xff1a; 2.修改數據&#xff08;update&#xff09; update 表名 set 字段名1值1&#xff0c;字段名2值2.....【where條件】 3.刪除數據&#xff0…

元年科技數據智能研發部負責人張亞東受邀為第十三屆中國PMO大會演講嘉賓

全國PMO專業人士年度盛會 北京元年科技股份有限公司數據智能研發部負責人張亞東先生受邀為PMO評論主辦的2024第十三屆中國PMO大會演講嘉賓&#xff0c;演講議題為“大模型時代&#xff0c;AI創新型工具提升項目管理效率”。大會將于6月29-30日在北京舉辦&#xff0c;敬請關注&a…

jmeter之HTTP請求和查看結果樹

一、HTTP請求作用&#xff1a; 可以發送post或get請求等請求可以向服務器發送參數或消息體數據可以進行文件上傳 HTTP請求&#xff1a;是線程組內的取樣器最常用的的一個原件 二、查看界面 添加一個HTTP請求&#xff1a;選擇線程組–添加–取樣器–HTTP請求 默認界面 名稱和…

ThreadLocal為什么會導致內存泄漏?

問題引出&#xff1a; ThreadLocal是為了解決什么問題而產生的&#xff1f; ThreadLocal發生內存泄漏的根本原因是什么&#xff1f; 如何避免內存泄漏的發生&#xff1f;定義 為了解決多個線程同時操作程序中的同一個變量而導致的數據不一致性的問題。 ??假設現在有兩個線程A…

如何獲取一個城市或者一個區域的玫瑰風向圖?

玫瑰風向圖是一種直觀展示風向和風速的圖形工具&#xff0c;它在氣象學、城市規劃、農業等領域都有廣泛的應用。那么&#xff0c;如何獲取某個城市或某個區域的玫瑰風向圖呢&#xff1f; 首先&#xff0c;我們可以借助互聯網資源獲取玫瑰風向圖。現代網絡技術發達&#xff0c;…

前端 防抖和節流

在前端開發中&#xff0c;防抖&#xff08;Debounce&#xff09;和節流&#xff08;Throttle&#xff09;是兩種常用的性能優化技術&#xff0c;尤其在處理頻繁觸發的事件時顯得尤為重要。無論是在用戶輸入、窗口調整大小&#xff0c;還是滾動事件中&#xff0c;這兩種技術都可…

3D 生成重建011-LucidDreamer 優化SDS過平滑結果的一種探索

3D 生成重建011-LucidDreamer 優化SDS過平滑結果的一種探索 文章目錄 0論文工作1論文方法2 效果 0論文工作 文本到3D生成的最新進展標志著生成模型的一個重要里程碑&#xff0c;為在各種現實場景中創建富有想象力的3D資產打開了新的可能性。雖然最近在文本到3D生成方面的進展…

自建公式,VBA在Excel中解一元一次方程

自建公式,VBA在Excel中解一元一次方程 文章目錄 前言一、運行效果圖二、操作思路三、代碼1.去除方程中未知數,將未知數轉為“*0”2.計算方程中常數3.計算方程中未知數的系數一,先將未知數替換成“*1”4.計算方程中未知數的系數二5.計算方程得數前言 小學必考內容:一元一次…