opencv 2 computer vision application programming第五章翻译

第五章 用生态学过滤方法改变图像

这一章我们讨论:
用形态过滤器磨损和扩大图像
用形态过滤器打开和关闭图像
用形态过滤器做边缘检测和角点检测
用水印分割图像
用抓取切割算法提取前景中物体

 

到google上找到了书对应的代码下载了,然后条码的边缘检测有了点想法。

  1 /*------------------------------------------------------------------------------------------*\
  2    This file contains material supporting chapter 5 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 #include <opencv2/core/core.hpp>
 19 #include <opencv2/imgproc/imgproc.hpp>
 20 #include <opencv2/highgui/highgui.hpp>
 21 #include "morphoFeatures.h"
 22 
 23 int main()
 24 {
 25     // Read input image
 26     cv::Mat image= cv::imread("C:/testdir/barcode5.jpg",0);
 27     if (!image.data)
 28         return 0;
 29 
 30     // Display the image
 31  //   cv::namedWindow("Image");
 32     cv::imshow("Image",image);
 33 
 34     // Create the morphological features instance
 35     MorphoFeatures morpho;
 36     morpho.setThreshold(40);
 37 
 38     // Get the edges
 39     cv::Mat edges;
 40     edges= morpho.getEdges(image);
 41 
 42     // Display the edge image
 43     cv::namedWindow("Edge Image");
 44     cv::imshow("Edge Image",edges);
 45 
 46     // Get the corners
 47     morpho.setThreshold(-1);
 48     cv::Mat corners;
 49     corners= morpho.getCorners(image);
 50     cv::morphologyEx(corners,corners,cv::MORPH_TOPHAT,cv::Mat());
 51     cv::threshold(corners, corners, 40, 255, cv::THRESH_BINARY_INV);
 52 
 53     // Display the corner image
 54     cv::namedWindow("Corner Image");
 55     cv::imshow("Corner Image",corners);
 56 
 57     // Display the corner on the image
 58     morpho.drawOnImage(corners,image);
 59     cv::namedWindow("Corners on Image");
 60     cv::imshow("Corners on Image",image);
 61 /*
 62     // Read and display image of square
 63     image= cv::imread("C:/testdir/square.jpg",0);
 64     cv::namedWindow("Square Image");
 65     cv::imshow("Square Image",image);
 66 
 67     // Creating the cross-shaped structuring element
 68     cv::Mat cross(5,5,CV_8U,cv::Scalar(0));
 69     for (int i=0; i<5; i++) {
 70 
 71       cross.at<uchar>(2,i)= 1;
 72       cross.at<uchar>(i,2)= 1;
 73     }
 74 
 75     // Dilate with a cross
 76     cv::Mat result;
 77     cv::dilate(image,result,cross);
 78 
 79     // Display the result
 80     cv::namedWindow("Dilated square with cross");
 81     cv::imshow("Dilated square with cross",result);
 82 
 83     // Creating the diamond-shaped structuring element
 84     cv::Mat diamond(5,5,CV_8U,cv::Scalar(1));
 85     diamond.at<uchar>(0,0)= 0;
 86     diamond.at<uchar>(0,1)= 0;
 87     diamond.at<uchar>(1,0)= 0;
 88     diamond.at<uchar>(4,4)= 0;
 89     diamond.at<uchar>(3,4)= 0;
 90     diamond.at<uchar>(4,3)= 0;
 91     diamond.at<uchar>(4,0)= 0;
 92     diamond.at<uchar>(4,1)= 0;
 93     diamond.at<uchar>(3,0)= 0;
 94     diamond.at<uchar>(0,4)= 0;
 95     diamond.at<uchar>(0,3)= 0;
 96     diamond.at<uchar>(1,4)= 0;
 97 
 98     // Erode with a diamond
 99     cv::Mat result2;
100     cv::erode(result,result2,diamond);
101 
102     // Display the result
103     cv::namedWindow("Eroded square with diamond");
104     cv::imshow("Eroded square with diamond",result2);
105 
106     // Combine the images into one
107     cv::Mat final(100,300,CV_8U);
108     cv::Mat window= final(cv::Rect(0,0,100,100));
109     image.copyTo(window);
110     window= final(cv::Rect(100,0,100,100));
111     result.copyTo(window);
112     window= final(cv::Rect(200,0,100,100));
113     result2.copyTo(window);
114 
115     // Display the combined result
116     cv::namedWindow("Combined");
117     cv::imshow("Combined",final);
118 
119     // Save combined result
120     cv::imwrite("squares.bmp",final);
121 */
122     cv::waitKey();
123 
124     return 0;
125 }

 

morphoFeatures.h:

  1 /*------------------------------------------------------------------------------------------*\
  2    This file contains material supporting chapter 5 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 MORPHOF
 19 #define MORPHOF
 20 
 21 #include <opencv2/core/core.hpp>
 22 #include <opencv2/imgproc/imgproc.hpp>
 23 
 24 class MorphoFeatures {
 25 
 26   private:
 27 
 28       // threshold to produce binary image
 29       int threshold;
 30       // structuring elements used in corner detection
 31       cv::Mat cross;
 32       cv::Mat diamond;
 33       cv::Mat square;
 34       cv::Mat x;
 35 
 36       void applyThreshold(cv::Mat& result) {
 37 
 38           // Apply threshold on result
 39           if (threshold>0)
 40             cv::threshold(result, result, threshold, 255, cv::THRESH_BINARY_INV);
 41       }
 42 
 43   public:
 44 
 45       MorphoFeatures() : threshold(-1), cross(5,5,CV_8U,cv::Scalar(0)), 
 46                                         diamond(5,5,CV_8U,cv::Scalar(1)), 
 47                                         square(5,5,CV_8U,cv::Scalar(1)),
 48                                         x(5,5,CV_8U,cv::Scalar(0)){
 49     
 50           // Creating the cross-shaped structuring element
 51           for (int i=0; i<5; i++) {
 52           
 53               cross.at<uchar>(2,i)= 1;
 54               cross.at<uchar>(i,2)= 1;                                    
 55           }
 56           
 57           // Creating the diamond-shaped structuring element
 58           diamond.at<uchar>(0,0)= 0;
 59           diamond.at<uchar>(0,1)= 0;
 60           diamond.at<uchar>(1,0)= 0;
 61           diamond.at<uchar>(4,4)= 0;
 62           diamond.at<uchar>(3,4)= 0;
 63           diamond.at<uchar>(4,3)= 0;
 64           diamond.at<uchar>(4,0)= 0;
 65           diamond.at<uchar>(4,1)= 0;
 66           diamond.at<uchar>(3,0)= 0;
 67           diamond.at<uchar>(0,4)= 0;
 68           diamond.at<uchar>(0,3)= 0;
 69           diamond.at<uchar>(1,4)= 0;
 70           
 71           // Creating the x-shaped structuring element
 72           for (int i=0; i<5; i++) {
 73           
 74               x.at<uchar>(i,i)= 1;
 75               x.at<uchar>(4-i,i)= 1;                                    
 76           }
 77       }
 78 
 79       void setThreshold(int t) {
 80 
 81           threshold= t;
 82       }
 83 
 84       int getThreshold() const {
 85 
 86           return threshold;
 87       }
 88 
 89       cv::Mat getEdges(const cv::Mat &image) {
 90 
 91           // Get the gradient image
 92           cv::Mat result;
 93           cv::morphologyEx(image,result,cv::MORPH_GRADIENT,cv::Mat());
 94 
 95           // Apply threshold to obtain a binary image
 96           applyThreshold(result);
 97 
 98           return result;
 99       }
100 
101       cv::Mat getCorners(const cv::Mat &image) {
102 
103           cv::Mat result;
104 
105           // Dilate with a cross    
106           cv::dilate(image,result,cross);
107 
108           // Erode with a diamond
109           cv::erode(result,result,diamond);
110 
111           cv::Mat result2;
112           // Dilate with a X    
113           cv::dilate(image,result2,x);
114 
115           // Erode with a square
116           cv::erode(result2,result2,square);
117 
118           // Corners are obtained by differencing
119           // the two closed images
120           cv::absdiff(result2,result,result);
121 
122           // Apply threshold to obtain a binary image
123           applyThreshold(result);
124 
125           return result;
126       }
127 
128       void drawOnImage(const cv::Mat& binary, cv::Mat& image) {
129                 
130           cv::Mat_<uchar>::const_iterator it= binary.begin<uchar>();
131           cv::Mat_<uchar>::const_iterator itend= binary.end<uchar>();
132 
133           // for each pixel    
134           for (int i=0; it!= itend; ++it,++i) {
135               if (!*it)
136                   cv::circle(image,cv::Point(i%image.step,i/image.step),5,cv::Scalar(255,0,0));
137           }
138       }
139 };
140 
141 
142 #endif

 

 

用500万像素的手机拍条码,边缘检测后虽然条码里面很乱但条码边框(黑色)能够确定了。

posted @ 2013-05-01 15:41  ChrisZZ  阅读(463)  评论(2编辑  收藏  举报