OpenCV學習C++接口:圖像銳化

利用拉普拉斯算子進行圖像銳化是數字圖像處理裏比較簡單的處理手段,下面的例子參考opencv 2 computer vision application programming cookbook,採用兩種方法對輸入圖像進行拉普拉斯銳化,原理比較簡單,故不贅述了。

編譯環境:VS2010+OpenCV2.3.1

編程細節:

  • 函數的形參表中,爲了防止修改輸入圖像image,故形參傳遞爲pass by conference-const,同時函數體中指向輸入圖像的指針也必須聲明爲指向const對象的指針,如const uchar *next = image.ptr<const uchar>(j);
  • cv::Mat::row()返回由單行或者單列組成的特定的cv::Mat實例,cv::Scalar(a,b,c)指定每個通道的特定值;
  • 第二種方法中,利用函數cv::filter2D(),需先創建一個核cv::Mat,並對核進行初始化


/***************************************************************
*
*   內容摘要:分別用兩種方法對輸入圖像進行拉普拉斯算子銳化,並比較
*             兩種方法的執行效率,從運行結果來看,第二種方法的效率
*
***************************************************************/


#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>


//輸入形參爲pass by conference-const,保證輸入的圖像不會被修改,並且爲傳遞引用
void sharpenImage0(const cv::Mat &image, cv::Mat &result)
{
    //爲輸出圖像分配內存
    result.create(image.size(),image.type());
    
    /*濾波核爲拉普拉斯核3x3:
                             0 -1 0
                            -1 5 -1
                             0 -1 0   
    */
    for(int j= 1; j<image.rows-1; ++j)
    {
        const uchar *previous = image.ptr<const uchar>(j-1);
        const uchar *current = image.ptr<const uchar>(j);
        const uchar *next = image.ptr<const uchar>(j+1);
        uchar *output = result.ptr<uchar>(j);
        for(int i= 1; i<image.cols-1; ++i)
        {
            *output++ = cv::saturate_cast<uchar>(5*current[i]-previous[i]-next[i]-current[i-1]-current[i+1]);  //saturate_cast<uchar>()保證結果在uchar範圍內
        }
    }
    result.row(0).setTo(cv::Scalar(0));
    result.row(result.rows-1).setTo(cv::Scalar(0));
    result.col(0).setTo(cv::Scalar(0));
    result.col(result.cols-1).setTo(cv::Scalar(0));
}


void sharpenImage1(const cv::Mat &image, cv::Mat &result)
{
    //創建並初始化濾波模板
    cv::Mat kernel(3,3,CV_32F,cv::Scalar(0));
    kernel.at<float>(1,1) = 5.0;
    kernel.at<float>(0,1) = -1.0;
    kernel.at<float>(1,0) = -1.0;
    kernel.at<float>(1,2) = -1.0;
    kernel.at<float>(2,1) = -1.0;


    result.create(image.size(),image.type());
    
    //對圖像進行濾波
    cv::filter2D(image,result,image.depth(),kernel);
}


int main(int argc, char* argv[])
{
    cv::Mat image = cv::imread("../boldt.jpg");
    cv::Mat image_gray;
    image_gray.create(image.size(),image.type());


    if(!image.data)
        return -1;
    if(image.channels() == 3)
        cv::cvtColor(image,image_gray,CV_RGB2GRAY);


    cv::Mat result;
    result.create(image_gray.size(),image_gray.type());
    double time_ = static_cast<double>(cv::getTickCount());
    sharpenImage0(image_gray,result);
    time_ = 1000*(static_cast<double>(cv::getTickCount())-time_)/cv::getTickFrequency();
    std::cout<<"time = "<<time_<<"ms"<<std::endl;


    cv::namedWindow("Image 1");
    cv::imshow("Image 1",result);


    cv::Mat result1;
    result1.create(image_gray.size(),image_gray.type());
    time_ = static_cast<double>(cv::getTickCount());
    sharpenImage1(image_gray,result1);
    time_ = 1000*static_cast<double>(cv::getTickCount()-time_)/cv::getTickFrequency();
    std::cout<<"time = "<<time_<<"ms"<<std::endl;


    cv::namedWindow("Image 2");
    cv::imshow("Image 2",result1);


    cv::waitKey();
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章