天天看點

android使用opencv之亮度與對比度處理

網上收集了兩種亮度與對比度的計算公式:

第一種:

一副圖像的亮度對比度調節屬于圖像的灰階線性變換,其公式如下:

y = [x - 127.5 * (1 - B)] * k + 127.5 * (1 + B);

x為調節前的像素值,y為調節後的像素值。

其中B取值[-1,1],調節亮度;

k調節對比度,arctan(k)取值[1,89],是以

k = tan( (45 + 44 * c) / 180 * pi );

其中c取值[-1,1]。通常我們用該值來設定對比度

特别的,

當B=0 時:y = (x - 127.5) * k + 127.5; 這時隻調節對比度。

當c=0 時,k = 1:y = x + 255 * B; 這時隻調節亮度。

第二種:g(i,j)=a*f(i,j)+b

參數f(i,j)表示源圖像像素

參數g(i,j)表示輸出圖像像素

參數a(需要滿足a>0)被稱為增益(gain),常常被用來控制圖像的對比度

參數b通常被稱為偏置,常常被用來控制圖像的亮度。

我更傾向于使用後者,公式簡單,經過測試,後者出入比較小。

NDK代碼如下:

JNIEXPORT jintArray JNICALL
Java_com_xy_opencv_ndk_1opencv002_MainActivity_lightPixels(JNIEnv *env, jclass type,
                                                           jintArray pixels_, jint w, jint h) {
    jint *pixels = env->GetIntArrayElements(pixels_, NULL);

    //顔色資料轉換 ARGB的顔色資料被轉成BGRA
    Mat img(h, w, CV_8UC4, pixels);

    //擷取行數和列數
    int row = img.rows;
    int col = img.cols;
       //亮度
    double b = ;
    //對比度 (值越小圖檔越灰暗)
    double c = ;

    for (int i = ; i < row; i++) {
        for (int j = ; j < col; j++) {
            //Blue
            img.at<Vec4b>(i, j)[] = (uchar) (img.at<Vec4b>(i, j)[] * c + b);
            //Green
            img.at<Vec4b>(i, j)[] = (uchar) (img.at<Vec4b>(i, j)[] * c + b);
            //Red
            img.at<Vec4b>(i, j)[] = (uchar) (img.at<Vec4b>(i, j)[] * c + b);
            //Alpha
            img.at<Vec4b>(i,j)[] = ;
        }
    }

    int size = w * h;

    jintArray result = env->NewIntArray(size);

    env->SetIntArrayRegion(result,,size,pixels);

    env->ReleaseIntArrayElements(pixels_, pixels, );

    return result;
}
           
android使用opencv之亮度與對比度處理