OpenCV2.4.10之samples_cpp_tutorial-code_learn-----ImgTrans(Laplace边缘检测和Sobel边缘检测,图像重映射)

本系列学习笔记参考自OpenCV2.4.10之 opencv\sources\samples\cpp\tutorial_code和 http://www.opencv.org.cn/opencvdoc/2.3.2/html/genindex.html


在图像处理中,往往需要对图像提取有效的边缘。本博文将介绍Laplace边缘检测和Sobel边缘检测,以及图像的重映射。


1.Laplace_Demo.cpp(Laplace边缘检测)
Demo源码及注释如下:
#include "stdafx.h"    //预编译头文件    

/**
Laplace变换检测边缘
 */

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>

using namespace cv;

/**
 *主函数
 */
int main( int, char** argv )
{

  Mat src, src_gray, dst;
  int kernel_size = 3;
  int scale = 1;
  int delta = 0;
  int ddepth = CV_16S;
  const char* window_name = "Laplace Demo";

  ///载入图片
  src = imread("D:\\opencv\\lena.png");

  if( !src.data )
    { return -1; }

  ///高斯滤波器进行模糊进而去除噪声
  GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT );

  ///将图像转换为灰度图
  cvtColor( src, src_gray, COLOR_RGB2GRAY );

  ///创建窗口
  namedWindow( window_name, WINDOW_AUTOSIZE );

  
  Mat abs_dst;
  ///Laplace变换
  Laplacian( src_gray, dst, ddepth, kernel_size, scale, delta, BORDER_DEFAULT );
  convertScaleAbs( dst, abs_dst );

  ///显示
  imshow( window_name, abs_dst );

  waitKey(0);

  return 0;
}
运行截图:
OpenCV2.4.10之samples_cpp_tutorial-code_learn-----ImgTrans(Laplace边缘检测和Sobel边缘检测,图像重映射)_第1张图片

函数Laplacian用于计算图像的Laplace边缘,函数原型为:C++: void Laplacian(InputArray src, OutputArray dst, int ddepth, int ksize=1, double scale=1, double delta=0, int borderType=BORDER_DEFAULT)参数src为灰度图,dst为与src大小相同,类型相同的Laplace边缘检测后的图像,ddepth用于描述图像的位深,ksize用于计算二阶导数滤波器的孔径大小,其值为奇数。scale为计算拉普拉斯值可选比例因子。delta为叠加在dst上的可选常量值。

2.Sobel_Demo.cpp(Sobel边缘检测)

demo源码及注释如下:
#include "stdafx.h"    //预编译头文件    

/**
Sobel边缘检测Demo
 */

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>

using namespace cv;

/**
 * 主函数
 */
int main( int, char** argv )
{

  Mat src, src_gray;
  Mat grad;
  const char* window_name = "Sobel Demo - Simple Edge Detector";
  int scale = 1;
  int delta = 0;
  int ddepth = CV_16S;

  ///载入图片
  src = imread("D:\\opencv\\lena.png");

  if( !src.data )
    { return -1; }

  GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT );

  ///转换为灰度图
  cvtColor( src, src_gray, COLOR_RGB2GRAY );

  ///创建窗口
  namedWindow( window_name, WINDOW_AUTOSIZE );

  Mat grad_x, grad_y;
  Mat abs_grad_x, abs_grad_y;

  ///X方向的梯度边缘
  Sobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT );
  convertScaleAbs( grad_x, abs_grad_x );

  //Y方向的梯度边缘
  Sobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT );
  convertScaleAbs( grad_y, abs_grad_y );

  ///图像总体边缘
  addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );

  imshow( window_name, grad );

  waitKey(0);

  return 0;
}
运行截图:
OpenCV2.4.10之samples_cpp_tutorial-code_learn-----ImgTrans(Laplace边缘检测和Sobel边缘检测,图像重映射)_第2张图片

Sobel函数的功能为通过Sobel算子计算 图像边缘,其函数声明为:C++: void Sobel(InputArray src, OutputArray dst, int ddepth, int xorder, int yorder, int ksize=3, double scale=1, double delta=0, intborderType=BORDER_DEFAULT ) 第一个参数src为输入图像,dst为输出图像,ddepth为输出图像位深,xorder与yorder分别为x方向与y方向的导数的阶数,ksize为sobel算子的大小,该值必须为奇数。


3.Remap_Demo.cpp(图像重映射)
demo源码及注释如下:
#include "stdafx.h"    //预编译头文件    

/**
图像重映射Demo
 */

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>

using namespace cv;

///全局变量
Mat src, dst;
Mat map_x, map_y;
const char* remap_window = "Remap demo";
int ind = 0;

///函数声明
void update_map( void );

/**
 * 主函数
 */
int main( int, char** argv )
{
  ///加载图片
  src = imread("D:\\opencv\\lena.png", 1 );

  ///创建于src图像大小小童的dst,map_x,map_y
  dst.create( src.size(), src.type() );
  map_x.create( src.size(), CV_32FC1 );
  map_y.create( src.size(), CV_32FC1 );

  ///创建窗口
  namedWindow( remap_window, WINDOW_AUTOSIZE );

  ///循环
  for(;;)
  {
    int c = waitKey( 1000 );

    if( (char)c == 27 )
      { break; }

    ///重映射
    update_map();
    remap( src, dst, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0) );

    //显示结果
    imshow( remap_window, dst );
  }
  return 0;
}

/**
 * 四种类型的重映射
 */
void update_map( void )
{
  ind = ind%4;

  for( int j = 0; j < src.rows; j++ )
    { for( int i = 0; i < src.cols; i++ )
     {
           switch( ind )
         {
         case 0: //高度缩小一半,并显示在中间
           if( i > src.cols*0.25 && i < src.cols*0.75 && j > src.rows*0.25 && j < src.rows*0.75 )
                 {
               map_x.at<float>(j,i) = 2*( i - src.cols*0.25f ) + 0.5f ;
               map_y.at<float>(j,i) = 2*( j - src.rows*0.25f ) + 0.5f ;
              }
           else
         { map_x.at<float>(j,i) = 0 ;
               map_y.at<float>(j,i) = 0 ;
                 }
                   break;
         case 1:  //图像上下颠倒
               map_x.at<float>(j,i) = (float)i ;
               map_y.at<float>(j,i) = (float)(src.rows - j) ;
           break;
             case 2://图像左右颠倒
               map_x.at<float>(j,i) = (float)(src.cols - i) ;
               map_y.at<float>(j,i) = (float)j ;
           break;
             case 3://图像上下颠倒的同时左右颠倒
               map_x.at<float>(j,i) = (float)(src.cols - i) ;
               map_y.at<float>(j,i) = (float)(src.rows - j) ;
           break;
             }
     }
    }
  ind++;
}
运行截图如下:
OpenCV2.4.10之samples_cpp_tutorial-code_learn-----ImgTrans(Laplace边缘检测和Sobel边缘检测,图像重映射)_第3张图片

remap的功能是实现图像的重映射。映射关系为:
\texttt{dst} (x,y) =  \texttt{src} (map_x(x,y),map_y(x,y))
函数原型为:C++: void remap(InputArray src, OutputArray dst, InputArray map1, InputArray map2, int interpolation, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())其中src为源图像,dst为目的图像。map1为x方向的映射关系,map2为y方向的映射关系。interpolation为插值方式。
OpenCV2.4.10之samples_cpp_tutorial-code_learn-----ImgTrans(Laplace边缘检测和Sobel边缘检测,图像重映射)_第4张图片

你可能感兴趣的:(opencv)