计算图像的拉普拉斯变换,使用方向滤波器检测边缘
来源:互联网 发布:煎饼侠 知乎 编辑:程序博客网 时间:2024/05/21 18:33
#if !defined LAPLACEZC#define LAPLACEZC#include <opencv2/core/core.hpp>#include <opencv2/imgproc/imgproc.hpp>class LaplacianZC { private: // original image cv::Mat img; // 32-bit float image containing the Laplacian cv::Mat laplace; // Aperture size of the laplacian kernel int aperture; public: LaplacianZC() : aperture(3) {} // Set the aperture size of the kernel void setAperture(int a) { aperture= a; } // Get the aperture size of the kernel int getAperture() const { return aperture; } // Compute the floating point Laplacian cv::Mat computeLaplacian(const cv::Mat& image) { // Compute Laplacian cv::Laplacian(image,laplace,CV_32F,aperture); // Keep local copy of the image // (used for zero-crossings) img= image.clone(); return laplace; } // Get the Laplacian result in 8-bit image // zero corresponds to gray level 128 // if no scale is provided, then the max value will be // scaled to intensity 255 // You must call computeLaplacian before calling this method cv::Mat getLaplacianImage(double scale=-1.0) { if (scale<0) { double lapmin, lapmax; cv::minMaxLoc(laplace,&lapmin,&lapmax); scale= 127/ std::max(-lapmin,lapmax); } cv::Mat laplaceImage; laplace.convertTo(laplaceImage,CV_8U,scale,128); return laplaceImage; } // Get a binary image of the zero-crossings // if the product of the two adjascent pixels is // less than threshold then this zero-crossing will be ignored cv::Mat getZeroCrossings(float threshold=1.0) { // Create the iterators cv::Mat_<float>::const_iterator it= laplace.begin<float>()+laplace.step1(); cv::Mat_<float>::const_iterator itend= laplace.end<float>(); cv::Mat_<float>::const_iterator itup= laplace.begin<float>(); // Binary image initialize to white cv::Mat binary(laplace.size(),CV_8U,cv::Scalar(255)); cv::Mat_<uchar>::iterator itout= binary.begin<uchar>()+binary.step1(); // negate the input threshold value threshold *= -1.0; for ( ; it!= itend; ++it, ++itup, ++itout) { // if the product of two adjascent pixel is negative // then there is a sign change if (*it * *(it-1) < threshold) *itout= 0; // horizontal zero-crossing else if (*it * *itup < threshold) *itout= 0; // vertical zero-crossing } return binary; } // Get a binary image of the zero-crossings // if the product of the two adjacent pixels is // less than threshold then this zero-crossing will be ignored cv::Mat getZeroCrossingsWithSobel(float threshold) { cv::Mat sx; cv::Sobel(img,sx,CV_32F,1,0,1); cv::Mat sy; cv::Sobel(img,sy,CV_32F,0,1,1); // Create the iterators cv::Mat_<float>::const_iterator it= laplace.begin<float>()+laplace.step1(); cv::Mat_<float>::const_iterator itend= laplace.end<float>(); cv::Mat_<float>::const_iterator itup= laplace.begin<float>(); cv::Mat_<float>::const_iterator itx= sx.begin<float>()+sx.step1(); cv::Mat_<float>::const_iterator ity= sy.begin<float>()+sy.step1(); // Binary image initialize to white cv::Mat binary(laplace.size(),CV_8U,cv::Scalar(255)); cv::Mat_<uchar>::iterator itout= binary.begin<uchar>()+binary.step1(); for ( ; it!= itend; ++it, ++itup, ++itout, ++itx, ++ity) { // if the product of two adjacent pixel is negative // then there is a sign change if (*it * *(it-1) < 0.0 && fabs(*ity) > threshold) *itout= 0; // horizontal zero-crossing else if (*it * *itup < 0.0 && fabs(*ity) > threshold) *itout= 0; // vertical zero-crossing } return binary; }};#endif#include <iostream>#include <iomanip>#include <opencv2/core/core.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <opencv2/highgui/highgui.hpp>#include "laplacianZC.h"int main(){// Read input imagecv::Mat image= cv::imread("d:/test/opencv/boldt.jpg",0);if (!image.data)return 0; // Display the imagecv::namedWindow("Original Image");cv::imshow("Original Image",image);// Compute Sobel X derivativecv::Mat sobelX;cv::Sobel(image,sobelX,CV_8U,1,0,3,0.4,128); // Display the imagecv::namedWindow("Sobel X Image");cv::imshow("Sobel X Image",sobelX);// Compute Sobel Y derivativecv::Mat sobelY;cv::Sobel(image,sobelY,CV_8U,0,1,3,0.4,128); // Display the imagecv::namedWindow("Sobel Y Image");cv::imshow("Sobel Y Image",sobelY);// Compute norm of Sobelcv::Sobel(image,sobelX,CV_16S,1,0);cv::Sobel(image,sobelY,CV_16S,0,1);cv::Mat sobel;//compute the L1 normsobel= abs(sobelX)+abs(sobelY);double sobmin, sobmax;cv::minMaxLoc(sobel,&sobmin,&sobmax);std::cout << "sobel value range: " << sobmin << " " << sobmax << std::endl;// Print window pixel valuesfor (int i=0; i<12; i++) {for (int j=0; j<12; j++)std::cout << std::setw(5) << static_cast<int>(sobel.at<short>(i+135,j+362)) << " ";std::cout << std::endl;}std::cout << std::endl;std::cout << std::endl;std::cout << std::endl;// Conversion to 8-bit image// sobelImage = -alpha*sobel + 255cv::Mat sobelImage;sobel.convertTo(sobelImage,CV_8U,-255./sobmax,255); // Display the imagecv::namedWindow("Sobel Image");cv::imshow("Sobel Image",sobelImage);// Apply threshold to Sobel norm (low threshold value)cv::Mat sobelThresholded;cv::threshold(sobelImage, sobelThresholded, 225, 255, cv::THRESH_BINARY); // Display the imagecv::namedWindow("Binary Sobel Image (low)");cv::imshow("Binary Sobel Image (low)",sobelThresholded);// Apply threshold to Sobel norm (high threshold value)cv::threshold(sobelImage, sobelThresholded, 190, 255, cv::THRESH_BINARY); // Display the imagecv::namedWindow("Binary Sobel Image (high)");cv::imshow("Binary Sobel Image (high)",sobelThresholded);// Compute Laplacian 3x3cv::Mat laplace;cv::Laplacian(image,laplace,CV_8U,1,1,128); // Display the imagecv::namedWindow("Laplacian Image");cv::imshow("Laplacian Image",laplace);// Print window pixel valuesfor (int i=0; i<12; i++) {for (int j=0; j<12; j++)std::cout << std::setw(5) << static_cast<int>(laplace.at<uchar>(i+135,j+362))-128 << " ";std::cout << std::endl;}std::cout << std::endl;std::cout << std::endl;std::cout << std::endl;// Compute Laplacian 7x7cv::Laplacian(image,laplace,CV_8U,7,0.01,128); // Display the image cv::namedWindow("Laplacian Image");cv::imshow("Laplacian Image",laplace);// Print window pixel valuesfor (int i=0; i<12; i++) {for (int j=0; j<12; j++)std::cout << std::setw(5) << static_cast<int>(laplace.at<uchar>(i+135,j+362))-128 << " ";std::cout << std::endl;} // Extract small windowcv::Mat window(image,cv::Rect(362,135,12,12));cv::namedWindow("Image window");cv::imshow("Image window",window);cv::imwrite("window.bmp",window);// Compute Laplacian using LaplacianZC classLaplacianZC laplacian;laplacian.setAperture(7);cv::Mat flap= laplacian.computeLaplacian(image);double lapmin, lapmax;cv::minMaxLoc(flap,&lapmin,&lapmax);std::cout << "Laplacian value range=[" << lapmin << "," << lapmax << "]\n";laplace= laplacian.getLaplacianImage();cv::namedWindow("Laplacian Image (7x7)");cv::imshow("Laplacian Image (7x7)",laplace);// Print Laplacian valuesstd::cout << std::endl;for (int i=0; i<12; i++) {for (int j=0; j<12; j++)std::cout << std::setw(5) << static_cast<int>(flap.at<float>(i+135,j+362)/100) << " ";std::cout << std::endl;}std::cout << std::endl;// Compute and display the zero-crossing pointscv::Mat zeros;zeros= laplacian.getZeroCrossings(lapmax);cv::namedWindow("Zero-crossings");cv::imshow("Zero-crossings",zeros);// Compute and display the zero-crossing points (Sobel version)zeros= laplacian.getZeroCrossings();zeros= laplacian.getZeroCrossingsWithSobel(50);cv::namedWindow("Zero-crossings (2)");cv::imshow("Zero-crossings (2)",zeros);// Print window pixel valuesfor (int i=0; i<12; i++) {for (int j=0; j<12; j++)std::cout << std::setw(2) << static_cast<int>(zeros.at<uchar>(i+135,j+362)) << " ";std::cout << std::endl;} // Display the image with windowcv::rectangle(image,cv::Point(362,135),cv::Point(374,147),cv::Scalar(255,255,255));cv::namedWindow("Original Image with window");cv::imshow("Original Image with window",image);cv::waitKey();return 0;}
1 0
- 计算图像的拉普拉斯变换,使用方向滤波器检测边缘
- 第六章图像滤波 方向滤波器边缘检测
- Opncv学习之使用方向滤波器检测边缘
- opencv之计算图像的拉普拉斯变换
- 我的OpenCV学习笔记(18):使用Sobel变化和拉普拉斯变换检测图像边沿
- 【OpenCV】图像的变换(三)-Canny边缘检测
- 使用 C# 实现图像的边缘检测
- 图像的边缘检测
- 图像的边缘检测
- 图像变换 - Canny算子边缘检测(cvCanny)
- 图像基本变换---Canny边缘检测算法
- MATLAB 图像拉普拉斯变换
- OpenCV2编程手册笔记之 6.5计算图像的拉普拉斯变换
- 图像变换 -拉普拉斯变换(cvLaplace)
- 边缘检测:Sobel、拉普拉斯算子
- OpenCV_(Laplacian Transform to find the edges)图像拉普拉斯变换查找边缘 图像识别
- 简单的图像边缘检测
- 检测图像边缘(包括障碍物的边缘,道路边缘)算法
- 三重循环矩阵乘法运行时间比较
- HDU1010
- 博客新开通
- HBase 在淘宝的应用和优化
- linux服务配置之DNS服务
- 计算图像的拉普拉斯变换,使用方向滤波器检测边缘
- Puzzle over “goto” goto背后发生了什么
- resin 配置多个实例
- CF 421D--Bug in code
- 单纯又饥渴的IT男程序员已经成为有心机的黑木耳们诱杀的对象了!
- HDU1240
- poj 1637 Sightseeing tour(混合图欧拉回路)
- poj3436 ACM Computer Factory
- 8259A--可编程中断控制器