OpenCV条码(6)简单实现

OpenCV读取条码图像,并利用EAN-13码的编码方式解码。

通过读入一张条码图像,识别对应的条码。

参考自  http://felix.abecassis.me/2011/10/opencv-barcode-reader-part-1/

/*version 0.01:
* 只是把upc的识别换成了ean的识别
* 第一个数字只能识别6或者9
* 图像要求为只包含条码
* 清晰度要求太高,500w手机拍照的照片不能完全识别
*----
* ChriZZ 2013.5.5
*/
1
#include <iostream> 2 #include <map> 3 #include <string> 4 #include <algorithm> 5 #include <cv.h> 6 #include <highgui.h> 7 8 using namespace std; 9 using namespace cv; 10 11 #define SPACE 0 12 #define BAR 255 13 14 typedef Mat_<uchar> MatU; 15 map<string, int> table[3]; 16 enum position{LEFT,RIGHT}; 17 int counter; //计数器,表示正在计算的条码编号(不包括起始编号) 18 int front; //起始编号 19 int mode[6]; //不同的起始编号对应着不同的左侧编码模式,比如起始编号为6对应“奇偶偶偶奇奇”,9对应“奇偶偶奇偶奇”。用1表示奇数,0表示偶数 20 21 void change01(string & s){//0和1互换。解码时使用 22 for(int i=0; i<s.length(); i++) 23 if(s[i]=='0') s[i]='1'; 24 else s[i]='0'; 25 } 26 27 void setup_map(){ //设定解码映射表table[], table[0]为左侧条码奇数型,table[1]为左侧条码偶数型,table[2]为右侧条码偶数型 28 string zode[10]={"0001101", "0011001", "0010011", "0111101", "0100011", "0110001", "0101111", "0111011", "0110111", "0001011"}; 29 for(int i=0; i<10; i++){ 30 table[0][zode[i]]=i; 31 string tmp=zode[i]; 32 change01(tmp); 33 table[2][tmp]=i; 34 reverse(tmp.begin(), tmp.end()); 35 table[1][tmp]=i; 36 } 37 } 38 void align_boundary(const MatU& img, Point& cur, int begin, int end){ 39 if (img(cur) == end){ 40 while (img(cur)==end) 41 ++cur.x; 42 }else{ 43 while (img(cur.y, cur.x-1)==begin) 44 --cur.x; 45 } 46 } 47 48 /*int read_digit(...) 49 *返回解析后得到的数字*/ 50 int read_digit(const MatU& img, Point& cur, int unit_width, int position){ 51 // Read the 7 consecutive bits. 52 int pattern[7] = {0, 0, 0, 0, 0, 0, 0}; 53 for (int i = 0; i < 7; i++){ 54 for (int j = 0; j < unit_width; j++){ 55 if (img(cur) == 255) 56 ++pattern[i]; 57 ++cur.x; 58 } 59 // See below for explanation. 60 if (pattern[i] == 1 && img(cur) == BAR 61 || pattern[i] == unit_width - 1 && img(cur) == SPACE) 62 --cur.x; 63 } 64 // Convert to binary, consider that a bit is set if the number of 65 // bars encountered is greater than a threshold. 66 int threshold = unit_width / 2; 67 string v=""; 68 for (int i = 0; i < 7; i++){ 69 if(pattern[i]>=threshold) v=v+"1"; 70 else v=v+"0"; 71 } 72 // Lookup digit value. 73 int digit; 74 if (position == LEFT){ 75 if(counter==0){ 76 if(v=="0001011"){//说明左侧数据第一个字符是6,将模式设定为“奇偶偶偶奇奇” 77 mode[0]=1; 78 mode[1]=0; 79 mode[2]=0; 80 mode[3]=0; 81 mode[4]=1; 82 mode[5]=1; 83 front=6; 84 }else{ //在中国除了69*开头的条码 应该都是97*开头的(ISBN) 85 mode[0]=1; 86 mode[1]=0; 87 mode[2]=0; 88 mode[3]=1; 89 mode[4]=0; 90 mode[5]=1; 91 front=9; 92 } 93 } 94 if(mode[counter]==1) digit=table[0][v]; //对应左侧奇数的编码方式 95 else digit=table[1][v]; //对应左侧偶数的编码方式 96 align_boundary(img, cur, SPACE, BAR); 97 }else{ 98 // Bitwise complement (only on the first 7 bits). 99 digit = table[2][v]; //对应右侧偶数的编码方式 100 align_boundary(img, cur, BAR, SPACE); 101 } 102 counter++; 103 return digit; 104 } 105 106 void skip_quiet_zone(const MatU& img, Point& cur){//略过空白区域 107 while (img(cur) == SPACE) 108 ++cur.x; 109 } 110 111 unsigned read_lguard(const MatU& img, Point& cur){//读取起始编号和左侧数据之间的 112 int widths[3] = { 0, 0, 0 }; 113 int pattern[3] = { BAR, SPACE, BAR }; 114 for (int i = 0; i < 3; i++) 115 while (img(cur) == pattern[i]){ 116 ++cur.x; 117 ++widths[i]; 118 } 119 return widths[0]; 120 } 121 122 void skip_mguard(const MatU& img, Point& cur){ //略过左侧数据和右侧数据之间的分界 123 int pattern[5] = { SPACE, BAR, SPACE, BAR, SPACE }; 124 for (int i = 0; i < 5; i++) 125 while (img(cur) == pattern[i]) 126 ++cur.x; 127 } 128 129 void read_barcode(const string& filename){ //读取条码主程序 130 counter=0; 131 MatU img = cv::imread(filename, 0); //载入图像 132 Size size = img.size(); 133 Point cur(0, size.height / 2); //cur表示当前位置 134 135 bitwise_not(img, img); 136 threshold(img, img, 128, 255, THRESH_BINARY); 137 skip_quiet_zone(img, cur); 138 139 setup_map(); //初始化解析表 140 141 int unit_width = read_lguard(img, cur); 142 143 vector<int> digits; 144 for (int i=0; i<6; i++){ //左侧数据解码 145 int d = read_digit(img, cur, unit_width, LEFT); 146 digits.push_back(d); 147 } 148 149 skip_mguard(img, cur); 150 151 for (int i = 0; i < 6; i++){ //右侧数据解码 152 int d = read_digit(img, cur, unit_width, RIGHT); 153 digits.push_back(d); 154 } 155 cout << front; //输出解码结果 156 for (int i = 0; i < 12; i++) 157 cout << digits[i]; 158 cout << endl; 159 waitKey(); 160 } 161 int main(){ 162 string imgname="C:/testdir/left.jpg"; 163 read_barcode(imgname); 164 return 0; 165 }

通过改进测量方法,用数学的手段减小了误差,提高了识别率,代码如下

/*version 0.02
*提高了识别精度
*第一位字符通过左侧6个数据反推得到,不仅仅限定于6和9
*------
* ChrisZZ 2012.5.5
*/
1
#include <iostream> 2 #include <map> 3 #include <string> 4 #include <cmath> 5 #include <algorithm> 6 #include <cv.h> 7 #include <highgui.h> 8 9 using namespace std; 10 using namespace cv; 11 12 #define SPACE 0 13 #define BAR 255 14 15 typedef Mat_<uchar> MatU; 16 map<string, int> table[3]; 17 enum position{LEFT,RIGHT}; 18 int front; //起始编号 19 int mode[6]; //不同的起始编号对应着不同的左侧编码模式,比如起始编号为6对应“奇偶偶偶奇奇”,9对应“奇偶偶奇偶奇”。用1表示奇数,0表示偶数 20 const double eps=1e-5; 21 int z; 22 23 int get_front(){ 24 string tmp=""; 25 int i; 26 for(i=0; i<6; i++){ 27 if(mode[i]==0) tmp=tmp+"0"; 28 else tmp=tmp+"1"; 29 } 30 if(tmp=="000000") return 0; 31 else if(tmp=="001011") return 1; 32 else if(tmp=="001101") return 2; 33 else if(tmp=="001110") return 3; 34 else if(tmp=="010011") return 4; 35 else if(tmp=="011001") return 5; 36 else if(tmp=="011100") return 6; 37 else if(tmp=="010101") return 7; 38 else if(tmp=="010110") return 8; 39 else if(tmp=="011010") return 9; 40 else return -1; 41 } 42 43 void align_boundary(const MatU& img, Point& cur, int begin, int end){ 44 if (img(cur) == end){ 45 while (img(cur)==end) 46 ++cur.x; 47 }else{ 48 while (img(cur.y, cur.x-1)==begin) 49 --cur.x; 50 } 51 } 52 53 /*int read_digit(...) 54 *返回解析后得到的数字*/ 55 int read_digit(const MatU& img, Point& cur, int position){ 56 int pattern[4] = {0,0,0,0}, i; 57 for (i=0; i<4; i++){ 58 int cur_val=img(cur); 59 while(img(cur)==cur_val){ 60 ++pattern[i]; 61 ++cur.x; 62 } 63 } 64 double sum=pattern[0]+pattern[1]+pattern[2]+pattern[3]; 65 double tmp1=(pattern[0]+pattern[1])*1.0; 66 double tmp2=(pattern[1]+pattern[2])*1.0; 67 int at1, at2; 68 if(tmp1/sum < 2.5/7) at1=2; 69 else if(tmp1/sum < 3.5/7) at1=3; 70 else if(tmp1/sum < 4.5/7) at1=4; 71 else at1=5; 72 73 if(tmp2/sum < 2.5/7) at2=2; 74 else if(tmp2/sum < 3.5/7) at2=3; 75 else if(tmp2/sum < 4.5/7) at2=4; 76 else at2=5; 77 78 int digit=-1; 79 80 if(position==LEFT){ 81 if(at1==2){ 82 if(at2==2) { 83 mode[z++]=0; 84 digit = 6; 85 } 86 else if(at2==3) { 87 mode[z++]=1; 88 digit = 0; 89 } 90 else if(at2==4) { 91 mode[z++]=0; 92 digit = 4; 93 } 94 else if(at2==5) { 95 mode[z++]=1; 96 digit = 3; 97 } 98 } 99 else if(at1==3){ 100 if(at2==2) { 101 mode[z++]=1; 102 digit = 9; 103 } 104 else if(at2==3) { 105 mode[z++]=0; 106 if(pattern[2]+1<pattern[3]) digit = 8; 107 else digit = 2; 108 } 109 else if(at2==4) { 110 mode[z++]=1; 111 if(pattern[1]+1<pattern[2]) digit = 7; 112 else digit = 1; 113 } 114 else if(at2==5) { 115 mode[z++]=0; 116 digit = 5; 117 } 118 } 119 else if(at1==4){ 120 if(at2==2) { 121 mode[z++]=0; 122 digit = 9; 123 } 124 else if(at2==3) { 125 mode[z++]=1; 126 if(pattern[1]+1<pattern[0]) digit = 8; 127 else digit = 2; 128 } 129 else if(at2==4) { 130 mode[z++]=0; 131 if(pattern[0]+1<pattern[1]) digit = 7; 132 else digit = 1; 133 } 134 else if(at2==5) { 135 mode[z++]=1; 136 digit = 5; 137 } 138 } 139 else if(at1==5){ 140 if(at2==2) { 141 mode[z++]=1; 142 digit = 6; 143 } 144 else if(at2==3) { 145 mode[z++]=0; 146 digit = 0; 147 } 148 else if(at2==4) { 149 mode[z++]=1; 150 digit = 4; 151 } 152 else if(at2==5) { 153 mode[z++]=0; 154 digit=3; 155 } 156 } 157 // align_boundary(img, cur, SPACE, BAR); 158 }else{ 159 if(at1==2){ 160 if(at2==2) digit = 6; 161 else if(at2==4) digit = 4; 162 } 163 else if(at1==3){ 164 if(at2==3) { 165 if(pattern[2]+1<pattern[3]) digit = 8; 166 else digit = 2; 167 } 168 else if(at2==5) digit = 5; 169 } 170 else if(at1==4){ 171 if(at2==2) digit = 9; 172 else if(at2==4) { 173 if(pattern[0]+1<pattern[1]) digit = 7; 174 else digit = 1; 175 } 176 } 177 else if(at1==5){ 178 if(at2==3) digit = 0; 179 else if(at2==5) digit=3; 180 } 181 // align_boundary(img, cur, SPACE, BAR); 182 } 183 return digit; 184 } 185 186 void skip_quiet_zone(const MatU& img, Point& cur){//略过空白区域 187 while (img(cur) == SPACE) 188 ++cur.x; 189 } 190 191 void read_lguard(const MatU& img, Point& cur){//通过读取左侧固定的“条空条”,获取单位长度。 192 int pattern[3] = { BAR, SPACE, BAR }; 193 for (int i=0; i<3; i++) 194 while (img(cur)==pattern[i]) 195 ++cur.x; 196 } 197 198 void skip_mguard(const MatU& img, Point& cur){ //略过左侧数据和右侧数据之间的分界 199 int pattern[5] = { SPACE, BAR, SPACE, BAR, SPACE }; 200 for (int i=0; i<5; i++) 201 while (img(cur)==pattern[i]) 202 ++cur.x; 203 } 204 205 void read_barcode(const string& filename){ //读取条码主程序 206 z=0; 207 MatU img = imread(filename, 0); //载入图像 208 Size size = img.size(); 209 Point cur(0, size.height / 2); //cur表示当前位置 210 bitwise_not(img, img); 211 threshold(img, img, 128, 255, THRESH_BINARY); 212 skip_quiet_zone(img, cur); 213 read_lguard(img, cur); 214 vector<int> digits; 215 for (int i=0; i<6; i++){ //左侧数据解码 216 int d = read_digit(img, cur, LEFT); 217 digits.push_back(d); 218 } 219 skip_mguard(img, cur); 220 for (int i = 0; i < 6; i++){ //右侧数据解码 221 int d = read_digit(img, cur, RIGHT); 222 digits.push_back(d); 223 } 224 //输出解码结果 225 int front=get_front(); 226 cout << front << " "; 227 for (int i = 0; i < 12; i++) 228 cout << digits[i] << " "; 229 cout << endl; 230 waitKey(); 231 } 232 int main(){ 233 string imgname="C:/testdir/barcode3.jpg"; 234 read_barcode(imgname); 235 return 0; 236 }

目前把摄像头调用和条码图片检测联系在一起,发现有问题,矩形区域的确认还没做好。。使用了多边形。

  1 #include <iostream>
  2 #include <map>
  3 #include <string>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <cv.h>
  7 #include <highgui.h>
  8 
  9 using namespace std;
 10 using namespace cv;
 11 
 12 #define SPACE 0
 13 #define BAR 255
 14 
 15 typedef Mat_<uchar> MatU;
 16 map<string, int> table[3];
 17 enum position{LEFT,RIGHT};
 18 int front;       //Æðʼ±àºÅ
 19 int mode[6];    //²»Í¬µÄÆðʼ±àºÅ¶ÔÓ¦×Ų»Í¬µÄ×ó²à±àÂëģʽ£¬±ÈÈçÆðʼ±àºÅΪ6¶ÔÓ¦¡°ÆæżżżÆæÆ桱£¬9¶ÔÓ¦¡°ÆæżżÆæżÆ桱¡£ÓÃ1±íʾÆæÊý£¬0±íʾżÊý
 20 const double eps=1e-5;
 21 int z;
 22 
 23 int get_front(){
 24     string tmp="";
 25     int i;
 26     for(i=0; i<6; i++){
 27         if(mode[i]==0) tmp=tmp+"0";
 28         else tmp=tmp+"1";
 29     }
 30     if(tmp=="000000") return 0;
 31     else if(tmp=="001011") return 1;
 32     else if(tmp=="001101") return 2;
 33     else if(tmp=="001110") return 3;
 34     else if(tmp=="010011") return 4;
 35     else if(tmp=="011001") return 5;
 36     else if(tmp=="011100") return 6;
 37     else if(tmp=="010101") return 7;
 38     else if(tmp=="010110") return 8;
 39     else if(tmp=="011010") return 9;
 40     else return -1;
 41 }
 42 
 43 void align_boundary(const MatU& img, Point& cur, int begin, int end){
 44     if (img(cur) == end){
 45         while (img(cur)==end)
 46             ++cur.x;
 47     }else{
 48         while (img(cur.y, cur.x-1)==begin)
 49             --cur.x;
 50     }
 51 }
 52 
 53 /*int read_digit(...)
 54  *·µ»Ø½âÎöºóµÃµ½µÄÊý×Ö*/
 55 int read_digit(const MatU& img, Point& cur, int position){
 56     // Read the 7 consecutive bits.
 57     int pattern[4] = {0,0,0,0};
 58     int i;
 59     for (i=0; i<4; i++){
 60         int cur_val=img(cur);
 61         while(img(cur)==cur_val){
 62             ++pattern[i];
 63             ++cur.x;
 64         }
 65         cout << endl;
 66         cout << "pattern[" << i << "]=" << pattern[i] << endl;
 67         // See below for explanation.
 68 /*        if ((pattern[i] == 1 && img(cur) == BAR) || (pattern[i] == unit_width - 1 && img(cur) == SPACE))
 69             --cur.x;*/
 70     }
 71 
 72 
 73 
 74     // Convert to binary, consider that a bit is set if the number of
 75     // bars encountered is greater than a threshold.
 76     double sum=pattern[0]+pattern[1]+pattern[2]+pattern[3];
 77     double tmp1=(pattern[0]+pattern[1])*1.0;
 78     double tmp2=(pattern[1]+pattern[2])*1.0;
 79     int at1, at2;
 80     if(tmp1/sum < 2.5/7)  at1=2;
 81     else if(tmp1/sum < 3.5/7) at1=3;
 82     else if(tmp1/sum < 4.5/7) at1=4;
 83     else at1=5;
 84 
 85     if(tmp2/sum < 2.5/7)  at2=2;
 86     else if(tmp2/sum < 3.5/7) at2=3;
 87     else if(tmp2/sum < 4.5/7) at2=4;
 88     else at2=5;
 89 
 90     int digit=-1;
 91 
 92     if(position==LEFT){
 93         if(at1==2){
 94             if(at2==2) {
 95                 mode[z++]=0;
 96                 digit = 6;
 97             }
 98             else if(at2==3) {
 99                 mode[z++]=1;
100                 digit = 0;
101             }
102             else if(at2==4) {
103                 mode[z++]=0;
104                 digit = 4;
105             }
106             else if(at2==5) {
107                 mode[z++]=1;
108                 digit = 3;
109             }
110         }
111         else if(at1==3){
112             if(at2==2) {
113                 mode[z++]=1;
114                 digit = 9;
115             }
116             else if(at2==3) {
117                 mode[z++]=0;
118                 if(pattern[2]+1<pattern[3]) digit = 8;
119                 else digit = 2;
120             }
121             else if(at2==4) {
122                 mode[z++]=1;
123                 if(pattern[1]+1<pattern[2]) digit = 7;
124                 else digit = 1;
125             }
126             else if(at2==5) {
127                 mode[z++]=0;
128                 digit = 5;
129             }
130         }
131         else if(at1==4){
132             if(at2==2) {
133                 mode[z++]=0;
134                 digit = 9;
135             }
136             else if(at2==3) {
137                 mode[z++]=1;
138                 if(pattern[1]+1<pattern[0]) digit = 8;
139                 else digit = 2;
140             }
141             else if(at2==4) {
142                 mode[z++]=0;
143                 if(pattern[0]+1<pattern[1]) digit = 7;
144                 else digit = 1;
145             }
146             else if(at2==5) {
147                 mode[z++]=1;
148                 digit = 5;
149             }
150         }
151         else if(at1==5){
152             if(at2==2) {
153                 mode[z++]=1;
154                 digit = 6;
155             }
156             else if(at2==3) {
157                 mode[z++]=0;
158                 digit = 0;
159             }
160             else if(at2==4) {
161                 mode[z++]=1;
162                 digit = 4;
163             }
164             else if(at2==5) {
165                 mode[z++]=0;
166                 digit=3;
167             }
168         }
169      //   align_boundary(img, cur, SPACE, BAR);
170     }else{
171         if(at1==2){
172             if(at2==2) digit = 6;
173             else if(at2==4) digit = 4;
174         }
175         else if(at1==3){
176             if(at2==3) {
177                 if(pattern[2]+1<pattern[3]) digit = 8;
178                 else digit = 2;
179             }
180             else if(at2==5) digit = 5;
181         }
182         else if(at1==4){
183             if(at2==2) digit = 9;
184             else if(at2==4) {
185                 if(pattern[0]+1<pattern[1]) digit = 7;
186                 else digit = 1;
187             }
188         }
189         else if(at1==5){
190             if(at2==3) digit = 0;
191             else if(at2==5) digit=3;
192         }
193      //   align_boundary(img, cur, SPACE, BAR);
194     }
195     cout << "digit=" << digit << endl;
196     return digit;
197 }
198 
199 void skip_quiet_zone(const MatU& img, Point& cur){//ÂÔ¹ý¿Õ°×ÇøÓò
200     while (img(cur) == SPACE)
201         ++cur.x;
202 }
203 
204 void read_lguard(const MatU& img, Point& cur){//ͨ¹ý¶ÁÈ¡×ó²à¹Ì¶¨µÄ¡°Ìõ¿ÕÌõ¡±£¬»ñÈ¡µ¥Î»³¤¶È¡£
205     int pattern[3] = { BAR, SPACE, BAR };
206     for (int i=0; i<3; i++)
207         while (img(cur)==pattern[i])
208             ++cur.x;
209 }
210 
211 void skip_mguard(const MatU& img, Point& cur){      //ÂÔ¹ý×ó²àÊý¾ÝºÍÓÒ²àÊý¾ÝÖ®¼äµÄ·Ö½ç
212     int pattern[5] = { SPACE, BAR, SPACE, BAR, SPACE };
213     for (int i=0; i<5; i++)
214         while (img(cur)==pattern[i])
215             ++cur.x;
216 }
217 
218 void read_barcode(MatU& img/*const string& filename*/){      //¶ÁÈ¡ÌõÂëÖ÷³ÌÐò
219     z=0;
220   //  MatU img = imread(filename, 0);         //ÔØÈëͼÏñ
221     Size size = img.size();
222     Point cur(0, size.height / 2);              //cur±íʾµ±Ç°Î»ÖÃ
223 
224     bitwise_not(img, img);
225     threshold(img, img, 128, 255, THRESH_BINARY);
226 
227     if (img(cur) != SPACE) return;
228 
229     skip_quiet_zone(img, cur);
230 
231     read_lguard(img, cur);
232 
233     vector<int> digits;
234     for (int i=0; i<6; i++){               //×ó²àÊý¾Ý½âÂë
235         int d = read_digit(img, cur, LEFT);
236         digits.push_back(d);
237     }
238 
239     skip_mguard(img, cur);
240 
241     for (int i = 0; i < 6; i++){        //ÓÒ²àÊý¾Ý½âÂë
242         int d = read_digit(img, cur, RIGHT);
243         digits.push_back(d);
244     }
245   //  cout << front;                      //Êä³ö½âÂë½á¹û
246     int front=get_front();
247     cout << front << " ";
248     for (int i = 0; i < 12; i++)
249         cout << digits[i] << " ";
250     cout << endl;
251     //waitKey();
252 }
253 
254 
255 
256 
257 // The "Square Detector" program.
258 // It loads several images sequentially and tries to find squares in
259 // each image
260 
261 #include "opencv2/core/core.hpp"
262 #include "opencv2/imgproc/imgproc.hpp"
263 #include "opencv2/highgui/highgui.hpp"
264 
265 #include <iostream>
266 #include <math.h>
267 #include <string.h>
268 
269 using namespace cv;
270 using namespace std;
271 
272 static void help()
273 {
274     cout <<
275     "\nA program using pyramid scaling, Canny, contours, contour simpification and\n"
276     "memory storage (it's got it all folks) to find\n"
277     "squares in a list of images pic1-6.png\n"
278     "Returns sequence of squares detected on the image.\n"
279     "the sequence is stored in the specified memory storage\n"
280     "Call:\n"
281     "./squares\n"
282     "Using OpenCV version %s\n" << CV_VERSION << "\n" << endl;
283 }
284 
285 
286 int thresh = 50, N = 11;
287 const char* wndname = "Square Detection Demo";
288 
289 // helper function:
290 // finds a cosine of angle between vectors
291 // from pt0->pt1 and from pt0->pt2
292 static double angle( Point pt1, Point pt2, Point pt0 )
293 {
294     double dx1 = pt1.x - pt0.x;
295     double dy1 = pt1.y - pt0.y;
296     double dx2 = pt2.x - pt0.x;
297     double dy2 = pt2.y - pt0.y;
298     return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
299 }
300 
301 // returns sequence of squares detected on the image.
302 // the sequence is stored in the specified memory storage
303 static void findSquares( const Mat& image, vector<vector<Point> >& squares )
304 {
305     squares.clear();
306 
307     Mat pyr, timg, gray0(image.size(), CV_8U), gray;
308 
309     // down-scale and upscale the image to filter out the noise
310     pyrDown(image, pyr, Size(image.cols/2, image.rows/2));
311     pyrUp(pyr, timg, image.size());
312     vector<vector<Point> > contours;
313 
314     // find squares in every color plane of the image
315     for( int c = 0; c < 3; c++ )
316     {
317         int ch[] = {c, 0};
318         mixChannels(&timg, 1, &gray0, 1, ch, 1);
319 
320         // try several threshold levels
321         for( int l = 0; l < N; l++ )
322         {
323             // hack: use Canny instead of zero threshold level.
324             // Canny helps to catch squares with gradient shading
325             if( l == 0 )
326             {
327                 // apply Canny. Take the upper threshold from slider
328                 // and set the lower to 0 (which forces edges merging)
329                 Canny(gray0, gray, 0, thresh, 5);
330                 // dilate canny output to remove potential
331                 // holes between edge segments
332                 dilate(gray, gray, Mat(), Point(-1,-1));
333             }
334             else
335             {
336                 // apply threshold if l!=0:
337                 //     tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0
338                 gray = gray0 >= (l+1)*255/N;
339             }
340 
341             // find contours and store them all as a list
342             findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
343 
344             vector<Point> approx;
345 
346             // test each contour
347             for( size_t i = 0; i < contours.size(); i++ )
348             {
349                 // approximate contour with accuracy proportional
350                 // to the contour perimeter
351                 approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);
352 
353                 // square contours should have 4 vertices after approximation
354                 // relatively large area (to filter out noisy contours)
355                 // and be convex.
356                 // Note: absolute value of an area is used because
357                 // area may be positive or negative - in accordance with the
358                 // contour orientation
359                 if( approx.size() == 4 &&
360                     fabs(contourArea(Mat(approx))) > 1000 &&
361                     isContourConvex(Mat(approx)) )
362                 {
363                     double maxCosine = 0;
364 
365                     for( int j = 2; j < 5; j++ )
366                     {
367                         // find the maximum cosine of the angle between joint edges
368                         double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
369                         maxCosine = MAX(maxCosine, cosine);
370                     }
371 
372                     // if cosines of all angles are small
373                     // (all angles are ~90 degree) then write quandrange
374                     // vertices to resultant sequence
375                     if( maxCosine < 0.3 )
376                         squares.push_back(approx);
377                 }
378             }
379         }
380     }
381 }
382 
383 bool zrange(const Point* p){
384 
385 
386     for(int i=0; i<4; i++){
387         if(!(p[i].x>0&&p[i].x<480&&p[i].y>0&&p[i].y<480))
388             return false;
389         cout << "(" <<  p[i].x << "," << p[i].y << ")" << endl;
390     }
391     return true;
392 }
393 
394 // the function draws all the squares in the image
395 static void drawSquares( Mat& image, const vector<vector<Point> >& squares )
396 {
397     for( size_t i = 0; i < squares.size(); i++ )
398     {
399         const Point* p = &squares[i][0];
400         int n = (int)squares[i].size();//actually n is always equals to 4
401      //   polylines(image, &p, &n, 1, true, Scalar(0,255,0), 3, CV_AA);
402 
403 
404 
405         //read_barcode(Rect(p[0], p[2]));
406       //  if(zrange(p))
407        // {
408             for(int j=0; j<4; j++){//使用line()函数替代polyline()函数画四边形
409                 line(image, p[j], p[(j+1)%4], Scalar( 255 ), 3, 8);
410             }
411 
412        //     MatU imageROI=image(Rect(p[0], p[2]));
413        //     MatU zcopy=Mat(imageROI);
414 
415       //      read_barcode(imageROI);
416        //     addWeighted(imageROI,1.0,zcopy,0.3,0.,image);
417         //    cout << endl;
418       //  }
419       //  vector<Point>approxedRectangle;
420       //  approxPolyDP(squares[i], approxedRectangle, 0., true);
421        // fillConvexPoly(image, &approxedRectangle[0], 4, 4);
422 
423       //  fillConvexPoly(Inputimage, inputarrayPoints, scalarColor, lineType, shift);
424 
425 
426     }
427 
428     imshow(wndname, image);
429 }
430 
431 int main(){
432 
433 /*
434     string msg="press q , Q or ESC to close this program";
435     cout << msg << endl;
436     VideoCapture capture(0);
437     if(!capture.isOpened()) return 1;
438     Mat image; //frame of video
439     string window_name="Extracted Frame";
440     namedWindow(window_name);
441     while(true){
442         capture >> image;
443         vector<vector<Point> > squares;
444         if(image.data){
445             findSquares(image, squares);
446             drawSquares(image, squares);
447         }
448         if(waitKey(30)>=0) break;
449     }
450     */
451     MatU image=imread("C:/testdir/barcode11.jpg", 0);
452     vector<vector<Point> > squares;
453     findSquares(image, squares);
454     drawSquares(image, squares);
455    // read_barcode(image);
456     waitKey(0);
457 /*
458 
459     Mat image=imread("C:/testdir/test1.jpg");
460     Mat roi=image(Rect(20, 20, 100, 100));
461 
462     Mat mask=Mat(roi);
463     cvtColor(mask, mask, CV_RGB2GRAY);
464 
465     addWeighted(roi, 1.0, mask, 0.3, 0., image);
466 
467     imshow("dfds", image);
468     waitKey(0);
469 
470 */
471 
472 
473 
474 
475     return 0;
476 }
477 
478 
479 
480 /*
481 
482 int main(){
483     Mat image=imread("C:/testdir/barcode1.jpg");
484     MatU logo=image(Rect(110, 200, 265, 230));
485 
486     read_barcode(logo);
487     addWeighted(logo, 1.0, logo, 0.3, 0., logo);
488     imshow("with logo", image);
489     waitKey(0);
490 
491 
492 }
493 
494 */
495 
496 
497 /*------------------------------------------------------------------------------------------*\
498    This file contains material supporting chapter 2 of the cookbook:
499    Computer Vision Programming using the OpenCV Library.
500    by Robert Laganiere, Packt Publishing, 2011.
501 
502    This program is free software; permission is hereby granted to use, copy, modify,
503    and distribute this source code, or portions thereof, for any purpose, without fee,
504    subject to the restriction that the copyright notice may not be removed
505    or altered from any source or altered source distribution.
506    The software is released on an as-is basis and without any warranties of any kind.
507    In particular, the software is not guaranteed to be fault-tolerant or free from failure.
508    The author disclaims all warranties with regard to this software, any use,
509    and any consequent failure, is purely the responsibility of the user.
510 
511    Copyright (C) 2010-2011 Robert Laganiere, www.laganiere.name
512 \*------------------------------------------------------------------------------------------*/
513 /*
514 
515 #include <vector>
516 #include <opencv2/core/core.hpp>
517 #include <opencv2/highgui/highgui.hpp>
518 
519 
520 int main()
521 {
522     cv::Mat image1;
523     cv::Mat image2;
524 
525     image1= cv::imread("C:/testdir/barcode1.jpg");
526     image2= cv::imread("C:/testdir/barcode19.jpg");
527     if (!image1.data)
528         return 0;
529     if (!image2.data)
530         return 0;
531 
532     cv::namedWindow("Image 1");
533     cv::imshow("Image 1",image1);
534     cv::namedWindow("Image 2");
535     cv::imshow("Image 2",image2);
536 
537     cv::Mat result;
538     cv::addWeighted(image1,0.7,image2,0.9,0.,result);
539 
540     cv::namedWindow("result");
541     cv::imshow("result",result);
542 
543     // using overloaded operator
544     result= 0.7*image1+0.9*image2;
545 
546     cv::namedWindow("result with operators");
547     cv::imshow("result with operators",result);
548 /*
549     image2= cv::imread("rain.jpg",0);
550 
551     // create vector of 3 images
552     std::vector<cv::Mat> planes;
553     // split 1 3-channel image into 3 1-channel images
554     cv::split(image1,planes);
555     // add to blue channel
556     planes[0]+= image2;
557     // merge the 3 1-channel images into 1 3-channel image
558     cv::merge(planes,result);
559 
560     cv::namedWindow("Result on blue channel");
561     cv::imshow("Result on blue channel",result);
562 
563     // read images
564     cv::Mat image= cv::imread("boldt.jpg");
565     cv::Mat logo= cv::imread("logo.bmp");
566 
567     // define image ROI
568     cv::Mat imageROI;
569     imageROI= image(cv::Rect(385,270,logo.cols,logo.rows));
570 
571     // add logo to image
572     cv::addWeighted(imageROI,1.0,logo,0.3,0.,imageROI);
573 
574     // show result
575     cv::namedWindow("with logo");
576     cv::imshow("with logo",image);
577 
578     // read images
579     image= cv::imread("boldt.jpg");
580     logo= cv::imread("logo.bmp");
581 
582     // define ROI
583     imageROI= image(cv::Rect(385,270,logo.cols,logo.rows));
584 
585     // load the mask (must be gray-level)
586     cv::Mat mask= cv::imread("logo.bmp",0);
587 
588     // copy to ROI with mask
589     logo.copyTo(imageROI,mask);
590 
591     // show result
592     cv::namedWindow("with logo 2");
593     cv::imshow("with logo 2",image);
594 
595     // read images
596     logo= cv::imread("logo.bmp",0);
597     image1= cv::imread("boldt.jpg");
598 
599     // split 3-channel image into 3 1-channel images
600     std::vector<cv::Mat> channels;
601     cv::split(image1,channels);
602 
603     imageROI= channels.at(1);
604 
605     cv::addWeighted(imageROI(cv::Rect(385,270,logo.cols,logo.rows)),1.0,
606                     logo,0.5,0.,imageROI(cv::Rect(385,270,logo.cols,logo.rows)));
607 
608     cv::merge(channels,image1);
609 
610     cv::namedWindow("with logo 3");
611     cv::imshow("with logo 3",image1);
612 
613     cv::waitKey();
614 
615     return 0;
616 }
617 
618 
619 
620 
621 
622 */

 今天打开Qt发现Qt抽了。。程序一直报错。把复杂的程序都注释了只剩下读入和显示一张图片的代码结果仍然报错。我确实有清理过项目和重新构建项目。诶,蛋疼。重新建立一个工程写吧。。

代码:读入图片,检测、圈出并截图显示 :宽度在50-280之间的矩形框

  1 #include "opencv2/core/core.hpp"
  2 #include "opencv2/imgproc/imgproc.hpp"
  3 #include "opencv2/highgui/highgui.hpp"
  4 
  5 #include <iostream>
  6 #include <math.h>
  7 #include <string.h>
  8 
  9 using namespace cv;
 10 using namespace std;
 11 
 12 
 13 #define SPACE 0
 14 #define BAR 255
 15 
 16 typedef Mat_<uchar> MatU;
 17 map<string, int> table[3];
 18 enum position{LEFT,RIGHT};
 19 int front;       //Æðʼ±àºÅ
 20 int mode[6];    //²»Í¬µÄÆðʼ±àºÅ¶ÔÓ¦×Ų»Í¬µÄ×ó²à±àÂëģʽ£¬±ÈÈçÆðʼ±àºÅΪ6¶ÔÓ¦¡°ÆæżżżÆæÆ桱£¬9¶ÔÓ¦¡°ÆæżżÆæżÆ桱¡£ÓÃ1±íʾÆæÊý£¬0±íʾżÊý
 21 const double eps=1e-5;
 22 int z;
 23 
 24 int get_front(){
 25     string tmp="";
 26     int i;
 27     for(i=0; i<6; i++){
 28         if(mode[i]==0) tmp=tmp+"0";
 29         else tmp=tmp+"1";
 30     }
 31     if(tmp=="000000") return 0;
 32     else if(tmp=="001011") return 1;
 33     else if(tmp=="001101") return 2;
 34     else if(tmp=="001110") return 3;
 35     else if(tmp=="010011") return 4;
 36     else if(tmp=="011001") return 5;
 37     else if(tmp=="011100") return 6;
 38     else if(tmp=="010101") return 7;
 39     else if(tmp=="010110") return 8;
 40     else if(tmp=="011010") return 9;
 41     else return -1;
 42 }
 43 
 44 void align_boundary(const MatU& img, Point& cur, int begin, int end){
 45     if (img(cur) == end){
 46         while (img(cur)==end)
 47             ++cur.x;
 48     }else{
 49         while (img(cur.y, cur.x-1)==begin)
 50             --cur.x;
 51     }
 52 }
 53 
 54 /*int read_digit(...)
 55  *·µ»Ø½âÎöºóµÃµ½µÄÊý×Ö*/
 56 int read_digit(const MatU& img, Point& cur, int position){
 57     // Read the 7 consecutive bits.
 58     int pattern[4] = {0,0,0,0};
 59     int i;
 60     for (i=0; i<4; i++){
 61         int cur_val=img(cur);
 62         while(img(cur)==cur_val){
 63             ++pattern[i];
 64             ++cur.x;
 65         }
 66         cout << endl;
 67         cout << "pattern[" << i << "]=" << pattern[i] << endl;
 68         // See below for explanation.
 69 /*        if ((pattern[i] == 1 && img(cur) == BAR) || (pattern[i] == unit_width - 1 && img(cur) == SPACE))
 70             --cur.x;*/
 71     }
 72 
 73 
 74 
 75     // Convert to binary, consider that a bit is set if the number of
 76     // bars encountered is greater than a threshold.
 77     double sum=pattern[0]+pattern[1]+pattern[2]+pattern[3];
 78     double tmp1=(pattern[0]+pattern[1])*1.0;
 79     double tmp2=(pattern[1]+pattern[2])*1.0;
 80     int at1, at2;
 81     if(tmp1/sum < 2.5/7)  at1=2;
 82     else if(tmp1/sum < 3.5/7) at1=3;
 83     else if(tmp1/sum < 4.5/7) at1=4;
 84     else at1=5;
 85 
 86     if(tmp2/sum < 2.5/7)  at2=2;
 87     else if(tmp2/sum < 3.5/7) at2=3;
 88     else if(tmp2/sum < 4.5/7) at2=4;
 89     else at2=5;
 90 
 91     int digit=-1;
 92 
 93     if(position==LEFT){
 94         if(at1==2){
 95             if(at2==2) {
 96                 mode[z++]=0;
 97                 digit = 6;
 98             }
 99             else if(at2==3) {
100                 mode[z++]=1;
101                 digit = 0;
102             }
103             else if(at2==4) {
104                 mode[z++]=0;
105                 digit = 4;
106             }
107             else if(at2==5) {
108                 mode[z++]=1;
109                 digit = 3;
110             }
111         }
112         else if(at1==3){
113             if(at2==2) {
114                 mode[z++]=1;
115                 digit = 9;
116             }
117             else if(at2==3) {
118                 mode[z++]=0;
119                 if(pattern[2]+1<pattern[3]) digit = 8;
120                 else digit = 2;
121             }
122             else if(at2==4) {
123                 mode[z++]=1;
124                 if(pattern[1]+1<pattern[2]) digit = 7;
125                 else digit = 1;
126             }
127             else if(at2==5) {
128                 mode[z++]=0;
129                 digit = 5;
130             }
131         }
132         else if(at1==4){
133             if(at2==2) {
134                 mode[z++]=0;
135                 digit = 9;
136             }
137             else if(at2==3) {
138                 mode[z++]=1;
139                 if(pattern[1]+1<pattern[0]) digit = 8;
140                 else digit = 2;
141             }
142             else if(at2==4) {
143                 mode[z++]=0;
144                 if(pattern[0]+1<pattern[1]) digit = 7;
145                 else digit = 1;
146             }
147             else if(at2==5) {
148                 mode[z++]=1;
149                 digit = 5;
150             }
151         }
152         else if(at1==5){
153             if(at2==2) {
154                 mode[z++]=1;
155                 digit = 6;
156             }
157             else if(at2==3) {
158                 mode[z++]=0;
159                 digit = 0;
160             }
161             else if(at2==4) {
162                 mode[z++]=1;
163                 digit = 4;
164             }
165             else if(at2==5) {
166                 mode[z++]=0;
167                 digit=3;
168             }
169         }
170      //   align_boundary(img, cur, SPACE, BAR);
171     }else{
172         if(at1==2){
173             if(at2==2) digit = 6;
174             else if(at2==4) digit = 4;
175         }
176         else if(at1==3){
177             if(at2==3) {
178                 if(pattern[2]+1<pattern[3]) digit = 8;
179                 else digit = 2;
180             }
181             else if(at2==5) digit = 5;
182         }
183         else if(at1==4){
184             if(at2==2) digit = 9;
185             else if(at2==4) {
186                 if(pattern[0]+1<pattern[1]) digit = 7;
187                 else digit = 1;
188             }
189         }
190         else if(at1==5){
191             if(at2==3) digit = 0;
192             else if(at2==5) digit=3;
193         }
194      //   align_boundary(img, cur, SPACE, BAR);
195     }
196     cout << "digit=" << digit << endl;
197     return digit;
198 }
199 
200 void skip_quiet_zone(const MatU& img, Point& cur){//ÂÔ¹ý¿Õ°×ÇøÓò
201     while (img(cur) == SPACE)
202         ++cur.x;
203 }
204 
205 void read_lguard(const MatU& img, Point& cur){//ͨ¹ý¶ÁÈ¡×ó²à¹Ì¶¨µÄ¡°Ìõ¿ÕÌõ¡±£¬»ñÈ¡µ¥Î»³¤¶È¡£
206     int pattern[3] = { BAR, SPACE, BAR };
207     for (int i=0; i<3; i++)
208         while (img(cur)==pattern[i])
209             ++cur.x;
210 }
211 
212 void skip_mguard(const MatU& img, Point& cur){      //ÂÔ¹ý×ó²àÊý¾ÝºÍÓÒ²àÊý¾ÝÖ®¼äµÄ·Ö½ç
213     int pattern[5] = { SPACE, BAR, SPACE, BAR, SPACE };
214     for (int i=0; i<5; i++)
215         while (img(cur)==pattern[i])
216             ++cur.x;
217 }
218 
219 bool isBar(MatU& img){
220     Size size = img.size();
221     Point cur(0, size.height / 2);
222     int cnt=0;//count the number of BAR-and-SPACE regions
223     if(img(cur)!=SPACE){
224         cnt=0;
225         return false;
226     }else{
227         while(img(cur)==SPACE)
228             cur.x++;
229         int statue=SPACE;
230         while(cur.x<img.cols){
231             if(img(cur)!=statue)
232                 cnt++;
233             if(cnt>20) return true;
234         }
235         return false;
236     }
237 }
238 
239 void read_barcode(MatU& img/*const string& filename*/){      //¶ÁÈ¡ÌõÂëÖ÷³ÌÐò
240 
241   //  if(isBar(img)) //isBar():judge weather img is a barcode region or not
242    //     return;
243 
244     z=0;
245   //  MatU img = imread(filename, 0);         //ÔØÈëͼÏñ
246     Size size = img.size();
247     Point cur(0, size.height / 2);              //cur±íʾµ±Ç°Î»ÖÃ
248 
249     bitwise_not(img, img);
250     threshold(img, img, 128, 255, THRESH_BINARY);
251 
252     if (img(cur) != SPACE) return;
253 
254     skip_quiet_zone(img, cur);
255 
256     read_lguard(img, cur);
257 
258     vector<int> digits;
259     for (int i=0; i<6; i++){               //×ó²àÊý¾Ý½âÂë
260         int d = read_digit(img, cur, LEFT);
261         digits.push_back(d);
262     }
263 
264     skip_mguard(img, cur);
265 
266     for (int i = 0; i < 6; i++){        //ÓÒ²àÊý¾Ý½âÂë
267         int d = read_digit(img, cur, RIGHT);
268         digits.push_back(d);
269     }
270   //  cout << front;                      //Êä³ö½âÂë½á¹û
271     int front=get_front();
272     cout << front << " ";
273     for (int i = 0; i < 12; i++)
274         cout << digits[i] << " ";
275     cout << endl;
276     //waitKey();
277 }
278 
279 static void help()
280 {
281     cout <<
282     "\nA program using pyramid scaling, Canny, contours, contour simpification and\n"
283     "memory storage (it's got it all folks) to find\n"
284     "squares in a list of images pic1-6.png\n"
285     "Returns sequence of squares detected on the image.\n"
286     "the sequence is stored in the specified memory storage\n"
287     "Call:\n"
288     "./squares\n"
289     "Using OpenCV version %s\n" << CV_VERSION << "\n" << endl;
290 }
291 
292 
293 int thresh = 50, N = 11;
294 const char* wndname = "Square Detection Demo";
295 
296 // helper function:
297 // finds a cosine of angle between vectors
298 // from pt0->pt1 and from pt0->pt2
299 static double angle( Point pt1, Point pt2, Point pt0 )
300 {
301     double dx1 = pt1.x - pt0.x;
302     double dy1 = pt1.y - pt0.y;
303     double dx2 = pt2.x - pt0.x;
304     double dy2 = pt2.y - pt0.y;
305     return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
306 }
307 
308 // returns sequence of squares detected on the image.
309 // the sequence is stored in the specified memory storage
310 static void findSquares( const Mat& image, vector<vector<Point> >& squares )
311 {
312     squares.clear();
313 
314     Mat pyr, timg, gray0(image.size(), CV_8U), gray;
315 
316     // down-scale and upscale the image to filter out the noise
317     pyrDown(image, pyr, Size(image.cols/2, image.rows/2));
318     pyrUp(pyr, timg, image.size());
319     vector<vector<Point> > contours;
320 
321     // find squares in every color plane of the image
322     for( int c = 0; c < 3; c++ )
323     {
324         int ch[] = {c, 0};
325         mixChannels(&timg, 1, &gray0, 1, ch, 1);
326 
327         // try several threshold levels
328         for( int l = 0; l < N; l++ )
329         {
330             // hack: use Canny instead of zero threshold level.
331             // Canny helps to catch squares with gradient shading
332             if( l == 0 )
333             {
334                 // apply Canny. Take the upper threshold from slider
335                 // and set the lower to 0 (which forces edges merging)
336                 Canny(gray0, gray, 0, thresh, 5);
337                 // dilate canny output to remove potential
338                 // holes between edge segments
339                 dilate(gray, gray, Mat(), Point(-1,-1));
340             }
341             else
342             {
343                 // apply threshold if l!=0:
344                 //     tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0
345                 gray = gray0 >= (l+1)*255/N;
346             }
347 
348             // find contours and store them all as a list
349             findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
350 
351             vector<Point> approx;
352 
353             // test each contour
354             for( size_t i = 0; i < contours.size(); i++ )
355             {
356                 // approximate contour with accuracy proportional
357                 // to the contour perimeter
358                 approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);
359 
360                 // square contours should have 4 vertices after approximation
361                 // relatively large area (to filter out noisy contours)
362                 // and be convex.
363                 // Note: absolute value of an area is used because
364                 // area may be positive or negative - in accordance with the
365                 // contour orientation
366                 if( approx.size() == 4 &&
367                     fabs(contourArea(Mat(approx))) > 1000 &&
368                     isContourConvex(Mat(approx)) )
369                 {
370                     double maxCosine = 0;
371 
372                     for( int j = 2; j < 5; j++ )
373                     {
374                         // find the maximum cosine of the angle between joint edges
375                         double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
376                         maxCosine = MAX(maxCosine, cosine);
377                     }
378 
379                     // if cosines of all angles are small
380                     // (all angles are ~90 degree) then write quandrange
381                     // vertices to resultant sequence
382                     if( maxCosine < 0.3 )
383                         squares.push_back(approx);
384                 }
385             }
386         }
387     }
388 }
389 
390 double dist(Point p1, const Point p2){
391     return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
392 }
393 
394 // the function draws all the squares in the image
395 static void drawSquares( Mat& image, const vector<vector<Point> >& squares )
396 {
397     for( size_t i = 0; i < squares.size(); i++ )
398     {
399         const Point* p = &squares[i][0];
400         double d1=dist(p[0], p[1]);
401         double d2=dist(p[1], p[2]);
402         if(d1<50 || d2<50 || d1>280 || d2>280) continue;//把宽度小于50和大于350的矩形过滤
403         cout << dist(p[0], p[1]) << endl;
404         cout << dist(p[1], p[2]) << endl;
405         for(int j=0; j<4; j++){//使用line()函数替代polyline()函数画四边形
406             line(image, p[j], p[(j+1)%4], Scalar( 255 ), 3, 8);
407         }
408 
409         MatU imageROI=image(Rect(Point(p[1].x,p[1].y), Point(p[3].x, p[3].y)));
410              MatU zcopy=Mat(imageROI);
411              imshow("sdfds", zcopy);
412 
413 
414              if(isBar(imageROI)){
415                  cout << "yes" << endl;
416                  read_barcode(imageROI);
417                  addWeighted(imageROI,1.0,zcopy,0.3,0.,image);
418              }
419 
420     }
421 
422     imshow(wndname, image);
423 }
424 
425 int main(int /*argc*/, char** /*argv*/)
426 {
427     help();
428     namedWindow( wndname, 1 );
429     vector<vector<Point> > squares;
430 
431 
432     string imgname="C:/testdir/barcode1.jpg";
433     Mat image = imread(imgname, 1);
434     if( image.empty() ) return -1;
435 
436     findSquares(image, squares);
437     drawSquares(image, squares);
438 
439     waitKey(0);
440 }
Greatness is never a given, it must be earned.
原文地址:https://www.cnblogs.com/zjutzz/p/3059533.html