Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3 | PointedEar | 1 | /*------------------------------------------------------------------------------------------*\ |
2 | This file contains material supporting chapter 2 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 <iostream> |
||
19 | |||
20 | #include <opencv2/core/core.hpp> |
||
21 | #include <opencv2/highgui/highgui.hpp> |
||
22 | #include <opencv2/imgproc/imgproc.hpp> |
||
23 | |||
24 | |||
25 | void sharpen(const cv::Mat &image, cv::Mat &result) { |
||
26 | |||
27 | result.create(image.size(), image.type()); // allocate if necessary |
||
28 | |||
29 | for (int j= 1; j<image.rows-1; j++) { // for all rows (except first and last) |
||
30 | |||
31 | const uchar* previous= image.ptr<const uchar>(j-1); // previous row |
||
32 | const uchar* current= image.ptr<const uchar>(j); // current row |
||
33 | const uchar* next= image.ptr<const uchar>(j+1); // next row |
||
34 | |||
35 | uchar* output= result.ptr<uchar>(j); // output row |
||
36 | |||
37 | for (int i=1; i<image.cols-1; i++) { |
||
38 | |||
39 | *output++= cv::saturate_cast<uchar>(5*current[i]-current[i-1]-current[i+1]-previous[i]-next[i]); |
||
40 | // output[i]= cv::saturate_cast<uchar>(5*current[i]-current[i-1]-current[i+1]-previous[i]-next[i]); |
||
41 | } |
||
42 | } |
||
43 | |||
44 | // Set the unprocess pixels to 0 |
||
45 | result.row(0).setTo(cv::Scalar(0)); |
||
46 | result.row(result.rows-1).setTo(cv::Scalar(0)); |
||
47 | result.col(0).setTo(cv::Scalar(0)); |
||
48 | result.col(result.cols-1).setTo(cv::Scalar(0)); |
||
49 | } |
||
50 | |||
51 | void sharpen2(const cv::Mat &image, cv::Mat &result) { |
||
52 | |||
53 | result.create(image.size(), image.type()); // allocate if necessary |
||
54 | |||
55 | int step= image.step1(); |
||
56 | const uchar* previous= image.data; // ptr to previous row |
||
57 | const uchar* current= image.data+step; // ptr to current row |
||
58 | const uchar* next= image.data+2*step; // ptr to next row |
||
59 | uchar *output= result.data+step; // ptr to output row |
||
60 | |||
61 | for (int j= 1; j<image.rows-1; j++) { // for each row (except first and last) |
||
62 | for (int i=1; i<image.cols-1; i++) { // for each column (except first and last) |
||
63 | |||
64 | output[i]= cv::saturate_cast<uchar>(5*current[i]-current[i-1]-current[i+1]-previous[i]-next[i]); |
||
65 | } |
||
66 | |||
67 | previous+= step; |
||
68 | current+= step; |
||
69 | next+= step; |
||
70 | output+= step; |
||
71 | } |
||
72 | |||
73 | // Set the unprocess pixels to 0 |
||
74 | result.row(0).setTo(cv::Scalar(0)); |
||
75 | result.row(result.rows-1).setTo(cv::Scalar(0)); |
||
76 | result.col(0).setTo(cv::Scalar(0)); |
||
77 | result.col(result.cols-1).setTo(cv::Scalar(0)); |
||
78 | } |
||
79 | |||
80 | void sharpen3(const cv::Mat &image, cv::Mat &result) { |
||
81 | |||
82 | cv::Mat_<uchar>::const_iterator it= image.begin<uchar>()+image.step; |
||
83 | cv::Mat_<uchar>::const_iterator itend= image.end<uchar>()-image.step; |
||
84 | cv::Mat_<uchar>::const_iterator itup= image.begin<uchar>(); |
||
85 | cv::Mat_<uchar>::const_iterator itdown= image.begin<uchar>()+2*image.step; |
||
86 | |||
87 | result.create(image.size(), image.type()); // allocate if necessary |
||
88 | cv::Mat_<uchar>::iterator itout= result.begin<uchar>()+result.step; |
||
89 | |||
90 | for ( ; it!= itend; ++it, ++itup, ++itdown) { |
||
91 | |||
92 | *itout= cv::saturate_cast<uchar>(*it *5 - *(it-1)- *(it+1)- *itup - *itdown); |
||
93 | } |
||
94 | } |
||
95 | |||
96 | void sharpen2D(const cv::Mat &image, cv::Mat &result) { |
||
97 | |||
98 | // Construct kernel (all entries initialized to 0) |
||
99 | cv::Mat kernel(3,3,CV_32F,cv::Scalar(0)); |
||
100 | // assigns kernel values |
||
101 | kernel.at<float>(1,1)= 5.0; |
||
102 | kernel.at<float>(0,1)= -1.0; |
||
103 | kernel.at<float>(2,1)= -1.0; |
||
104 | kernel.at<float>(1,0)= -1.0; |
||
105 | kernel.at<float>(1,2)= -1.0; |
||
106 | |||
107 | //filter the image |
||
108 | cv::filter2D(image,result,image.depth(),kernel); |
||
109 | } |
||
110 | |||
111 | int main() |
||
112 | { |
||
113 | cv::Mat image= cv::imread("boldt.jpg",0); |
||
114 | if (!image.data) |
||
115 | return 0; |
||
116 | |||
117 | cv::Mat result; |
||
118 | result.create(image.size(),image.type()); |
||
119 | |||
120 | double time= static_cast<double>(cv::getTickCount()); |
||
121 | sharpen(image, result); |
||
122 | time= (static_cast<double>(cv::getTickCount())-time)/cv::getTickFrequency(); |
||
123 | std::cout << "time= " << time << std::endl; |
||
124 | |||
125 | cv::namedWindow("Image"); |
||
126 | cv::imshow("Image",result); |
||
127 | |||
128 | image= cv::imread("boldt.jpg",0); |
||
129 | time= static_cast<double>(cv::getTickCount()); |
||
130 | sharpen3(image, result); |
||
131 | time= (static_cast<double>(cv::getTickCount())-time)/cv::getTickFrequency(); |
||
132 | std::cout << "time 3= " << time << std::endl; |
||
133 | |||
134 | cv::namedWindow("Image 3"); |
||
135 | cv::imshow("Image 3",result); |
||
136 | |||
137 | image= cv::imread("boldt.jpg",0); |
||
138 | time= static_cast<double>(cv::getTickCount()); |
||
139 | sharpen2D(image, result); |
||
140 | time= (static_cast<double>(cv::getTickCount())-time)/cv::getTickFrequency(); |
||
141 | std::cout << "time 2D= " << time << std::endl; |
||
142 | |||
143 | cv::namedWindow("Image 2D"); |
||
144 | cv::imshow("Image 2D",result); |
||
145 | |||
146 | cv::waitKey(); |
||
147 | |||
148 | return 0; |
||
149 | } |
||
150 | |||
151 |