Go to most recent revision | Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 3 | PointedEar | 1 | /*------------------------------------------------------------------------------------------*\ |
| 2 | This file contains material supporting chapter 6 of the cookbook: |
||
| 3 | Computer Vision Programming using the OpenCV Library. |
||
| 4 | by Robert Laganiere, Packt Publishing, 2011. |
||
| 5 | |||
| 6 | This program is free software; permission is hereby granted to use, copy, modify, |
||
| 7 | and distribute this source code, or portions thereof, for any purpose, without fee, |
||
| 8 | subject to the restriction that the copyright notice may not be removed |
||
| 9 | or altered from any source or altered source distribution. |
||
| 10 | The software is released on an as-is basis and without any warranties of any kind. |
||
| 11 | In particular, the software is not guaranteed to be fault-tolerant or free from failure. |
||
| 12 | The author disclaims all warranties with regard to this software, any use, |
||
| 13 | and any consequent failure, is purely the responsibility of the user. |
||
| 14 | |||
| 15 | Copyright (C) 2010-2011 Robert Laganiere, www.laganiere.name |
||
| 16 | \*------------------------------------------------------------------------------------------*/ |
||
| 17 | |||
| 18 | #if !defined LAPLACEZC |
||
| 19 | #define LAPLACEZC |
||
| 20 | |||
| 21 | #include <opencv2/core/core.hpp> |
||
| 22 | #include <opencv2/imgproc/imgproc.hpp> |
||
| 23 | |||
| 24 | class LaplacianZC { |
||
| 25 | |||
| 26 | private: |
||
| 27 | |||
| 28 | // original image |
||
| 29 | cv::Mat img; |
||
| 30 | |||
| 31 | // 32-bit float image containing the Laplacian |
||
| 32 | cv::Mat laplace; |
||
| 33 | // Aperture size of the laplacian kernel |
||
| 34 | int aperture; |
||
| 35 | |||
| 36 | public: |
||
| 37 | |||
| 38 | LaplacianZC() : aperture(3) {} |
||
| 39 | |||
| 40 | // Set the aperture size of the kernel |
||
| 41 | void setAperture(int a) { |
||
| 42 | |||
| 43 | aperture= a; |
||
| 44 | } |
||
| 45 | |||
| 46 | // Get the aperture size of the kernel |
||
| 47 | int getAperture() const { |
||
| 48 | |||
| 49 | return aperture; |
||
| 50 | } |
||
| 51 | |||
| 52 | // Compute the floating point Laplacian |
||
| 53 | cv::Mat computeLaplacian(const cv::Mat& image) { |
||
| 54 | |||
| 55 | |||
| 56 | // Compute Laplacian |
||
| 57 | cv::Laplacian(image,laplace,CV_32F,aperture); |
||
| 58 | |||
| 59 | // Keep local copy of the image |
||
| 60 | // (used for zero-crossings) |
||
| 61 | img= image.clone(); |
||
| 62 | |||
| 63 | return laplace; |
||
| 64 | } |
||
| 65 | |||
| 66 | // Get the Laplacian result in 8-bit image |
||
| 67 | // zero corresponds to gray level 128 |
||
| 68 | // if no scale is provided, then the max value will be |
||
| 69 | // scaled to intensity 255 |
||
| 70 | // You must call computeLaplacian before calling this method |
||
| 71 | cv::Mat getLaplacianImage(double scale=-1.0) { |
||
| 72 | |||
| 73 | if (scale<0) { |
||
| 74 | |||
| 75 | double lapmin, lapmax; |
||
| 76 | cv::minMaxLoc(laplace,&lapmin,&lapmax); |
||
| 77 | |||
| 78 | scale= 127/ std::max(-lapmin,lapmax); |
||
| 79 | } |
||
| 80 | |||
| 81 | cv::Mat laplaceImage; |
||
| 82 | laplace.convertTo(laplaceImage,CV_8U,scale,128); |
||
| 83 | |||
| 84 | return laplaceImage; |
||
| 85 | } |
||
| 86 | |||
| 87 | // Get a binary image of the zero-crossings |
||
| 88 | // if the product of the two adjascent pixels is |
||
| 89 | // less than threshold then this zero-crossing will be ignored |
||
| 90 | cv::Mat getZeroCrossings(float threshold=1.0) { |
||
| 91 | |||
| 92 | // Create the iterators |
||
| 93 | cv::Mat_<float>::const_iterator it= laplace.begin<float>()+laplace.step1(); |
||
| 94 | cv::Mat_<float>::const_iterator itend= laplace.end<float>(); |
||
| 95 | cv::Mat_<float>::const_iterator itup= laplace.begin<float>(); |
||
| 96 | |||
| 97 | // Binary image initialize to white |
||
| 98 | cv::Mat binary(laplace.size(),CV_8U,cv::Scalar(255)); |
||
| 99 | cv::Mat_<uchar>::iterator itout= binary.begin<uchar>()+binary.step1(); |
||
| 100 | |||
| 101 | // negate the input threshold value |
||
| 102 | threshold *= -1.0; |
||
| 103 | |||
| 104 | for ( ; it!= itend; ++it, ++itup, ++itout) { |
||
| 105 | |||
| 106 | // if the product of two adjascent pixel is negative |
||
| 107 | // then there is a sign change |
||
| 108 | if (*it * *(it-1) < threshold) |
||
| 109 | *itout= 0; // horizontal zero-crossing |
||
| 110 | else if (*it * *itup < threshold) |
||
| 111 | *itout= 0; // vertical zero-crossing |
||
| 112 | } |
||
| 113 | |||
| 114 | return binary; |
||
| 115 | } |
||
| 116 | |||
| 117 | // Get a binary image of the zero-crossings |
||
| 118 | // if the product of the two adjacent pixels is |
||
| 119 | // less than threshold then this zero-crossing will be ignored |
||
| 120 | cv::Mat getZeroCrossingsWithSobel(float threshold) { |
||
| 121 | |||
| 122 | cv::Mat sx; |
||
| 123 | cv::Sobel(img,sx,CV_32F,1,0,1); |
||
| 124 | cv::Mat sy; |
||
| 125 | cv::Sobel(img,sy,CV_32F,0,1,1); |
||
| 126 | |||
| 127 | // Create the iterators |
||
| 128 | cv::Mat_<float>::const_iterator it= laplace.begin<float>()+laplace.step1(); |
||
| 129 | cv::Mat_<float>::const_iterator itend= laplace.end<float>(); |
||
| 130 | cv::Mat_<float>::const_iterator itup= laplace.begin<float>(); |
||
| 131 | cv::Mat_<float>::const_iterator itx= sx.begin<float>()+sx.step1(); |
||
| 132 | cv::Mat_<float>::const_iterator ity= sy.begin<float>()+sy.step1(); |
||
| 133 | |||
| 134 | // Binary image initialize to white |
||
| 135 | cv::Mat binary(laplace.size(),CV_8U,cv::Scalar(255)); |
||
| 136 | cv::Mat_<uchar>::iterator itout= binary.begin<uchar>()+binary.step1(); |
||
| 137 | |||
| 138 | for ( ; it!= itend; ++it, ++itup, ++itout, ++itx, ++ity) { |
||
| 139 | |||
| 140 | // if the product of two adjacent pixel is negative |
||
| 141 | // then there is a sign change |
||
| 142 | if (*it * *(it-1) < 0.0 && fabs(*ity) > threshold) |
||
| 143 | *itout= 0; // horizontal zero-crossing |
||
| 144 | else if (*it * *itup < 0.0 && fabs(*ity) > threshold) |
||
| 145 | *itout= 0; // vertical zero-crossing |
||
| 146 | } |
||
| 147 | |||
| 148 | return binary; |
||
| 149 | } |
||
| 150 | |||
| 151 | }; |
||
| 152 | |||
| 153 | |||
| 154 | #endif |