OpenCV(cv::convertScaleAbs())

做梦当财神發表於2024-09-23

目錄
  • 1. 函式定義
  • 2. 原理
  • 3. 示例
  • 4. 引數作用詳解
    • 4.1 alpha 的作用
    • 4.2 beta 的作用
  • 5. 應用場景
  • 6. cv::convertScaleAbs()cv::normalize() 的區別
  • 總結



cv::convertScaleAbs() 是 OpenCV 中用於將影像畫素值縮放並轉換為 8 位無符號整數型別的函式。它常用於處理計算結果為浮點數或負值的影像,特別是在影像處理過程中,如應用拉普拉斯運算元、Sobel 運算元等邊緣檢測操作後。



1. 函式定義

void cv::convertScaleAbs(
    InputArray src, 
    OutputArray dst, 
    double alpha = 1, 
    double beta = 0
);

引數:

  1. src:

    • 輸入陣列或影像。可以是任意深度的單通道或多通道陣列,如 CV_32FCV_64FCV_16S 等。
  2. dst:

    • 輸出陣列或影像。dst 總是一個 8 位無符號整數影像(CV_8U),這是由 convertScaleAbs() 函式保證的。
  3. alpha:

    • 可選的縮放因子。預設為 1.0。此引數用來對輸入影像的每個畫素值進行縮放,結果為:dst(i) = saturate_cast<uchar>(alpha * src(i) + beta)
  4. beta:

    • 可選的新增常數。預設為 0。此引數在縮放之後向每個畫素值新增一個偏移量。


2. 原理

convertScaleAbs() 主要執行以下三個步驟:

  1. 縮放: 將輸入影像中每個畫素值乘以一個縮放因子 alpha。這在處理如梯度或導數影像時非常有用,可以放大影像中數值較小的變化。

  2. 偏移: 在縮放後的畫素值上加上一個常數 beta,可以用於調整影像的亮度。

  3. 轉換到 8 位無符號整數型別: 函式將結果取絕對值並轉換為 8 位無符號整數。具體來說,負值會被轉換為正值,浮點數會被截斷為整數,而超過 255 的值會被裁剪到 255。函式內部使用 saturate_cast<uchar>() 來確保值保持在 [0, 255] 範圍內。



3. 示例

#include <opencv2/opencv.hpp>
using namespace cv;

int main() {
    // 讀取影像
    Mat src = imread("image.jpg", IMREAD_GRAYSCALE);
    
    // 檢查是否成功載入影像
    if (src.empty()) {
        return -1;
    }

    // 假設我們使用了 Sobel 運算元或其他操作,並得到了一個 CV_16S 的影像
    Mat grad_x;
    Sobel(src, grad_x, CV_16S, 1, 0); // 計算 X 方向的梯度

    // 使用 convertScaleAbs 將 CV_16S 轉換為 CV_8U
    Mat abs_grad_x;
    convertScaleAbs(grad_x, abs_grad_x);

    // 顯示結果
    imshow("Sobel X", abs_grad_x);
    waitKey(0);

    return 0;
}
  1. 使用 Sobel 運算元:

    • 在該示例中,我們首先對影像應用了 Sobel 運算元來計算 X 方向的梯度。Sobel 的輸出通常為 CV_16S,因為導數計算會導致負值。
  2. convertScaleAbs() 的應用:

    • convertScaleAbs() 用於將 Sobel 輸出的 16 位有符號整數影像(CV_16S)轉換為 8 位無符號整數影像(CV_8U)。它首先將影像畫素取絕對值(避免負值),然後裁剪到 [0, 255] 範圍內。


4. 引數作用詳解

4.1 alpha 的作用

alpha 是一個縮放因子,常用於對輸入影像的值進行比例調整。比如,在處理影像梯度時,梯度值可能比較小或比較大,直接顯示會顯得不明顯。透過調整 alpha,可以放大或縮小這些值。

double alpha = 0.5;  // 縮小梯度值
convertScaleAbs(grad_x, abs_grad_x, alpha);

4.2 beta 的作用

beta 是一個偏移量,通常用於整體調整影像的亮度。比如,給影像中的每個畫素增加一個常數值來提高亮度。

double beta = 50;  // 提高影像亮度
convertScaleAbs(grad_x, abs_grad_x, 1, beta);


5. 應用場景

  1. 梯度影像處理: cv::convertScaleAbs() 常用於處理導數和梯度影像,比如在應用 Sobel 運算元或拉普拉斯運算元後,結果影像可能包含負值,必須將其轉換為正值並且適合顯示。

  2. 浮點數影像處理: 如果你有浮點數格式(如 CV_32F)的影像結果,convertScaleAbs() 可以將其縮放到可顯示的範圍內。

  3. 歸一化: 可以透過設定合適的 alphabeta 值,對影像進行縮放和歸一化處理。



6. cv::convertScaleAbs()cv::normalize() 的區別

  • cv::normalize() 是一種標準化函式,用於將影像畫素值縮放到一個指定的範圍。它的功能更為廣泛,可以用於最大最小值歸一化、L2 歸一化等。
  • cv::convertScaleAbs() 是一種縮放與取絕對值的函式,更加簡化,常用於將結果轉換為適合顯示的 8 點陣圖像。


總結

cv::convertScaleAbs() 是 OpenCV 中非常實用的工具,它透過縮放和取絕對值,將高精度的影像資料轉換為適合顯示的 8 位無符號整數影像。它在處理邊緣檢測、梯度運算、浮點影像時尤為常用,並且能夠有效防止負值和過大數值帶來的顯示問題。



相關文章