歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

OpenCV基礎篇之查找表

OpenCV基礎篇之查找表

程序及分析

/*
 * FileName : lookup_table.cpp
 * Author  : xiahouzuoxin @163.com
 * Version  : v1.0
 * Date    : Sun 01 Jun 2014 04:35:37 PM CST
 * Brief    :
 *
 * Copyright (C) MICL,USTB
 */

#include <cv.h>
#include <highgui.h>

using namespace std;
using namespace cv;

#define QUAN_VAL1          (10)
#define QUAN_VAL2          (100)

void CreateLookupTable(Mat& table, uchar quan_val)
{
    table.create(1,256,CV_8UC1);

    uchar *p = table.data;
    for(int i = 0; i < 256; ++i)
    {
        p[i] = quan_val*(i/quan_val);
    }
}

int main(int argc, char *argv[])
{
    Mat img;
    Mat out1;
    Mat out2;

    if (argc < 2) {
        cout << "Please input image file name." << endl;
        return -1;
    }

    img = imread(argv[1], 1);


    Mat table;
    CreateLookupTable(table, QUAN_VAL1);
    LUT(img, table, out1);
    CreateLookupTable(table, QUAN_VAL2);
    LUT(img, table, out2);  // Call OpenCV function

    namedWindow("Lena", CV_WINDOW_NORMAL);
    imshow("Lena", img);
    namedWindow("QUAN_VAL=10", CV_WINDOW_NORMAL);
    imshow("QUAN_VAL=10", out1);
    namedWindow("QUAN_VAL=100", CV_WINDOW_NORMAL);
    imshow("QUAN_VAL=100", out2);

    waitKey(0);

    return 0;
}
 1.
為什麼要使用查找表?

一般的灰度圖像有256個灰度級,而有時我們並不需要這麼精確的灰度級(嚴重影響運算時間),比如黑白圖像。這意味著我們以一個新的輸入值劃分當前的顏色空間,比如灰度到黑白色,將0~127灰度值直接賦值0,128~255賦值1,最終得到較少的黑白兩色。查找表就扮演著這種降低灰度級而提高運算速度的角色。量化前和量化後的灰度值可以用下面的表達式表示:

 

其中Q表示量化級別,如取10,表示:灰度值1-10用灰度值1表示,灰度值11-20用灰度值11表示,以此類推!

2.
使用上面公式和查找表有毛關系,當然沒有,但上面公式代價就是要對圖片遍歷的每個灰度值都計算一次。因此,本著程序設計中的“以空間換時間”的基本算法策略,引入查找表,查找表就是將0~255個灰度值量化後的結果提前計算好存儲在一個表中,上面程序中的CreateLookupTable就是完成該功能的函數。從程序中可以看出,查找表的數據結構定義為Mat類型。

3.
有了查找表後,要對圖像中的像素灰度值進行替換,OpenVC提供了使用查找表直接計算出量化灰度級後圖像的函數——LUT,其函數原型為:
//! transforms array of numbers using a lookup table: dst(i)=lut(src(i))
CV_EXPORTS_W void LUT(InputArray src, InputArray lut, OutputArray dst,
                      int interpolation=0);

 注意哦,我們程序中定義的查找表類型為Mat,這裡LUT的輸入輸出參數類型怎麼是InputArray和OutputArray。在OpenCV中,InputArray/OutputArray這個接口類可以是Mat、Mat_、Mat_、vector、vector>、vector。

也就意味著當你看refman或者源代碼時,如果看見函數的參數類型是InputArray/OutputArray型時,把上訴幾種類型作為參數都是可以的。

另外,請注意,InputArray/OutputArray只能作為函數的形參參數使用,不要試圖聲明一個InputArray類型的變量,OutputArray也只是InputArray的派生。還有,還有就是OutputArrayOfArrays、InputOutputArray、InputOutputArrayOfArrays都是OutputArray的別名,碰到別慌張!

效果

江南好,千鐘美酒,一曲滿庭芳

左邊是原始圖片;中間是量化值Q=10時的結果,信息丟失很少;右邊是量化值Q=100的圖片,很多信息丟失了,但也別有一番風味。

--------------------------------------分割線 --------------------------------------

Ubuntu Linux下安裝OpenCV2.4.1所需包 http://www.linuxidc.com/Linux/2012-08/68184.htm

Ubuntu 12.04 安裝 OpenCV2.4.2 http://www.linuxidc.com/Linux/2012-09/70158.htm

CentOS下OpenCV無法讀取視頻文件 http://www.linuxidc.com/Linux/2011-07/39295.htm

Ubuntu 12.04下安裝OpenCV 2.4.5總結 http://www.linuxidc.com/Linux/2013-06/86704.htm

Ubuntu 10.04中安裝OpenCv2.1九步曲 http://www.linuxidc.com/Linux/2010-09/28678.htm

基於QT和OpenCV的人臉識別系統 http://www.linuxidc.com/Linux/2011-11/47806.htm

--------------------------------------分割線 --------------------------------------

Copyright © Linux教程網 All Rights Reserved