OpenCV学习篇之六 遍历图像和邻域操作

程序功能:
对图像进行锐化

程序:

// learn_sharpen.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include 
#include 
#include 
#include 
using namespace std;

void sharpen(const cv::Mat &image, cv::Mat &result) {

    result.create(image.size(), image.type()); // 如有必要则分配图像

    for (int j= 1; j<image.rows-1; j++) { // 处理除了第一行和最后一行之外的所有行

        const uchar* previous= image.ptr(j-1); // 上一行
        const uchar* current= image.ptr(j);    // 当前行
        const uchar* next= image.ptr(j+1);     // 下一行

        uchar* output= result.ptr(j);    //输出行

        for (int i=1; i<image.cols-1; i++) {

            *output++= cv::saturate_cast(5*current[i]-current[i-1]-current[i+1]-previous[i]-next[i]);  
        }
    }

    // 将未处理的像素设置为0
    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 sharpen2D(const cv::Mat &image, cv::Mat &result) {

    // 构造核(所有项都初始化为0)
    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>(2,1)= -1.0;
    kernel.at<float>(1,0)= -1.0;
    kernel.at<float>(1,2)= -1.0;

    //对图像进行滤波
    cv::filter2D(image,result,image.depth(),kernel);
}


int _tmain(int argc, _TCHAR* argv[])
{
    cv::Mat image= cv::imread("D:\\image\\boldt.jpg",0);
    if (!image.data)
        return 0;

    cv::namedWindow("image");
    cv::imshow("image",image);

    cv::Mat result;
    result.create(image.size(),image.type());
    sharpen(image, result);


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


    //image= cv::imread("D:\\image\\boldt.jpg",0);

    sharpen2D(image, result);


    cv::namedWindow("Image 2D");
    cv::imshow("Image 2D",result);

    cv::waitKey();

    return 0;
}

程序运行结果:
OpenCV学习篇之六 遍历图像和邻域操作_第1张图片
图1 原图

OpenCV学习篇之六 遍历图像和邻域操作_第2张图片
图2 锐化图1

OpenCV学习篇之六 遍历图像和邻域操作_第3张图片
图3 锐化图2

程序分析:
对图像进行锐化是基于拉普拉斯算子,将一幅图像减去它经过拉普拉斯滤波之后的图像,这幅图像的边缘部分将得到放大,即细节部分更加锐化。这个锐化算子的计算方式如下:
sharpened_pixel=5*current-left-right-up-down;
其中,left代表在当前像素左边紧挨着它的像素,up代表在当前像素上边紧挨着它的像素,以此类推。函数sharpen()就是如此实现的,效果如图2.
函数sharpen2D()是采用OpenCV提供的锐化滤波器cv::filter2D()函数来实现的,其核矩阵为:
0 -1 0
-1 5 -1
0 -1 0

Filter2D函数:
对图像做卷积
void cvFilter2D( const CvArr* src, CvArr* dst,
const CvMat* kernel,
CvPoint anchor=cvPoint(-1,-1));

define cvConvolve2D cvFilter2D
src
输入图像.
dst
输出图像.
kernel
卷积核, 单通道浮点矩阵. 如果想要应用不同的核于不同的通道,先用 cvSplit 函数分解图像到单个色彩通道上,然后单独处理。
anchor
核的锚点表示一个被滤波的点在核内的位置。 锚点应该处于核内部。缺省值 (-1,-1) 表示锚点在核中心。
函数 Filter2D 对图像进行线性滤波,支持 In-place 操作。当核运算部分超出输入图像时,函数从最近邻的图像内部象素差值得到边界外面的象素值。

你可能感兴趣的:(OpenCV学习)