9.1.10. 裁剪和縮放演算法,用於 sh_mobile_ceu_camera 驅動¶
作者:Guennadi Liakhovetski <g.liakhovetski@gmx.de>
9.1.10.1. 術語¶
感測器縮放:水平和垂直縮放,由感測器驅動配置 主機縮放:-”- 主機驅動 組合縮放:sensor_scale * host_scale
9.1.10.2. 通用縮放/裁剪方案¶
-1--
|
-2-- -\
| --\
| --\
+-5-- . -- -3-- -\
| `... -\
| `... -4-- . - -7..
| `.
| `. .6--
|
| . .6'-
| .´
| ... -4'- .´
| ...´ - -7'.
+-5'- .´ -/
| -- -3'- -/
| --/
| --/
-2'- -/
|
|
-1'-
在上面的圖表中,減號和斜槓表示“真實”資料量,點和重音符號表示“有用”資料,基本上是 CEU 縮放和裁剪後的輸出,映射回客戶端的源平面。
這種配置可以透過使用者請求生成
S_CROP(左 / 上 = (5) - (1), 寬 / 高 = (5’) - (5)) S_FMT(寬 / 高 = (6’) - (6))
這裡
(1) 到 (1’) - 整個最大寬度或高度 (1) 到 (2) - 感測器裁剪的左側或頂部 (2) 到 (2’) - 感測器裁剪的寬度或高度 (3) 到 (3’) - 感測器縮放 (3) 到 (4) - CEU 裁剪的左側或頂部 (4) 到 (4’) - CEU 裁剪的寬度或高度 (5) 到 (5’) - 應用於 CEU 裁剪的寬度或高度的反向感測器縮放 (2) 到 (5) - 應用於 CEU 裁剪的左側或頂部的反向感測器縮放 (6) 到 (6’) - CEU 縮放 - 使用者視窗
9.1.10.3. S_FMT¶
不要觸控輸入矩形 - 它已經是最佳的。
計算當前感測器縮放
scale_s = ((2’) - (2)) / ((3’) - (3))
2. 計算“有效”輸入裁剪(感測器子視窗)- CEU 裁剪按當前感測器縮放比例縮放回輸入視窗 - 這是使用者 S_CROP
width_u = (5’) - (5) = ((4’) - (4)) * scale_s
3. 計算從“有效”輸入視窗到請求的使用者視窗的新組合縮放
scale_comb = width_u / ((6’) - (6))
4. 透過將組合縮放應用於真實輸入視窗來計算感測器輸出視窗
width_s_out = ((7’) - (7)) = ((2’) - (2)) / scale_comb
對感測器輸出視窗應用迭代感測器 S_FMT。
subdev->video_ops->s_fmt(.width = width_s_out)
檢索感測器輸出視窗 (g_fmt)
計算新的感測器縮放
scale_s_new = ((3’)_new - (3)_new) / ((2’) - (2))
8. 計算新的 CEU 裁剪 - 將感測器縮放應用於先前計算的“有效”裁剪
width_ceu = (4’)_new - (4)_new = width_u / scale_s_new left_ceu = (4)_new - (3)_new = ((5) - (2)) / scale_s_new
使用 CEU 裁剪裁剪到新視窗
ceu_crop(.width = width_ceu, .left = left_ceu)
使用 CEU 縮放縮放到請求的使用者視窗
scale_ceu = width_ceu / width
9.1.10.4. S_CROP¶
“...規範沒有定義原點或單位。但是,按照慣例,驅動程式應水平計數相對於 0H 的未縮放樣本。”
我們選擇遵循該建議並將裁剪單位解釋為客戶端輸入畫素。
裁剪按以下 6 個步驟執行
從感測器請求完全使用者矩形。
如果較小 - 迭代直到獲得更大的矩形。 結果:感測器裁剪到 2 : 2’,目標裁剪 5 : 5’,當前輸出格式 6’ - 6。
在上一步中,感測器已嘗試儘可能好地保留其輸出幀,但它可能已更改。 再次檢索它。
感測器縮放到 3 : 3’。 感測器的縮放是 (2’ - 2) / (3’ - 3)。 計算中間視窗:4’ - 4 = (5’ - 5) * (3’ - 3) / (2’ - 2)
計算並應用主機縮放 = (6’ - 6) / (4’ - 4)
計算並應用主機裁剪:6 - 7 = (5 - 2) * (6’ - 6) / (5’ - 5)