OpenCV扫描图像并访问相邻像素

OpenCV扫描图像并访问相邻像素,在图像处理中经常有这样的处理函数,它在计算每个像素的数值时,需要使用周边像素的值。如果相邻像素在上一行或下一行,就需要同时扫描图像的多行。本文将介绍实现方法。

准备工作

为了便于说明问题,我们将使用一个锐化图像的处理函数。它基于拉普拉斯算子。在图像处理领域有一个众所周知的结论:如果从图像中减去拉普拉斯算子部分,图像的边缘就会放大,因而图像会变得更加尖锐。
可以用以下方法计算锐化的数值:

sharpened_pixel= 5*current-left-right-up-down;

这里的left是与当前像素相邻的左侧像素,up是上一行的相邻像素,以此类推。

如何实现

这里不能使用就地处理,用户必须提供一个输出图像。图像扫描中使用了三个指针,一个表示当前行、一个表示上面的行、一个表示下面的行。另外,因为在计算每一个像素时都需要访问与它相邻的像素,所以有些像素的值是无法计算的,比如第一行、最后一行和第一列、最后一列的像素。这个循环可以这样写:

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

              // 判断是否需要分配图像数据。如果需要,就分配

              result.create(image.size(), image.type());
              int nchannels= image.channels(); // 获得通道数
              // 处理所有行(除了第一行和最后一行)
              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=nchannels; i<(image.cols-1)*nchannels; i++) {

                // 应用锐化算子
                *output++= cv::saturate_cast<uchar>(
                        5*current[i]-current[i-nchannels]-
                        current[i+nchannels]-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));
          }

注意这个函数是如何同时适应灰度图像和彩色图像的。如果我们在测试用的灰度图像上执行该函数,将得到如下结果:

OpenCV扫描图像并访问相邻像素

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!