用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 }

转载于:https://www.cnblogs.com/zjutzz/archive/2013/05/04/3059533.html

OpenCV条码(6)简单实现相关推荐

  1. python怎么建立画板_Python基于opencv实现的简单画板功能示例

    本文实例讲述了Python基于opencv实现的简单画板功能.分享给大家供大家参考,具体如下: import cv2 import numpy as np drawing = False # true ...

  2. python通过opencv使用图片制作简单视频(亲测)

    最近在学习视频制作,但是做起来太浪费时间了,我就一直在想能否使用python等脚本实现制作视频,因为我看视频网站上很多营销号视频就是通过图片制作视频的,播放量还不错,我准备试一试. 一.目标 1.自动 ...

  3. 使用Opencv构建一个简单的图像相似检测器(MSE、SSIM)

    介绍 作为人类,我们通常非常善于发现图像中的差异.例如,常见的游戏--两张图像找不同.现在让我们玩下这个游戏吧,首先让我们看看上面的图像,三十秒内看看是否能够从中找出有什么不同的地方.         ...

  4. python3+opencv+tkinter开发简单的人脸识别小程序

    学校里有门图像处理的课程最终需要提交一个图像处理系统, 正好之前对于opencv有些了解,就简单的写一个人脸识别小程序吧 效果图如下 笔者IDE使用Pycharm,GUI编程直接使用内置的tkinte ...

  5. 官网opencv练习题 最简单的多物体分离技术

    题目来源:https://docs.opencv.org/4.1.0/df/d9d/tutorial_py_colorspaces.html    最底部 题目: Try to find a way ...

  6. [机器学习]基于OpenCV实现最简单的数字识别

    http://blog.csdn.net/jinzhuojun/article/details/8579416 本文将基于OpenCV实现简单的数字识别.这里以游戏Angry Birds为例,通过以下 ...

  7. python使用opencv模块画简单的图形

    opencv模块提供了画图函数接口,这些函数接口可以很方便的绘制简单地图形. cv2.line():绘制线段函数 cv2.circle():绘制圆 cv2.rectangle():绘制矩形 cv2.e ...

  8. openCV人脸识别简单案例

    1 基础 我们使用机器学习的方法完成人脸检测,首先需要大量的正样本图像(面部图像)和负样本图像(不含面部的图像)来训练分类器.我们需要从其中提取特征.下图中的 Haar 特征会被使用,就像我们的卷积核 ...

  9. opencv之图片简单压缩

    一.简单常用 #include <opencv2/opencv.hpp> #include<iostream> #include <math.h> #include ...

最新文章

  1. 怎么连接屏幕_手机屏幕坏了也可以操作?这办法学会了再不怕碎屏
  2. 为什么我们需要开源的系统芯片?
  3. 通过KNN算法,确定球星的风格(很水)
  4. 小心内存也会引起蓝屏
  5. 查看并开启MySQL的log-bin和general_log日志
  6. Linux 内核打印级别
  7. Arduino笔记-解决上传时出现avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00问题
  8. centos装java配件_CentOS安装JAVA
  9. android插件数字,Android自定义控件实现带文本与数字的圆形进度条
  10. Ehcache详细解读
  11. AutoWare 使用
  12. SVN实现自动更新(Windows平台)
  13. Android开发之ListView中Adapter的优化
  14. Python入门教程三:显示'Welcome to Python'五次
  15. tp5 in_array 在 view页面用法
  16. Educational Codeforces Round 61 (Rated for Div. 2) D. Stressful Training(贪心+二分+优先队列)
  17. 打印论文是单面还是双面?
  18. vue 获取input光标位置,并实现插入模板语法。
  19. XSS漏洞利用——键盘记录
  20. C++上机报告 利用公式计算π=4(1-1/3+1/5-1/7+1/9-...)的近似值,直到括号中最后一项的绝对值小于0.000001为止。

热门文章

  1. Dll入口函数参数详解
  2. 做为技术人员为什么要写博客?
  3. 防火墙(7)——禁止具体协议
  4. XP MSTSC连接WIN7或WIN8问题
  5. pixhawk软件架构
  6. 割点、割边(桥) tarjan
  7. malloc 背后的系统知识(虚拟内存地址)
  8. TypeError系列之:TypeError: conv2d(): argument 'input' (position 1) must be Tensor, not NoneType
  9. java也可以做黑客?
  10. 有机晶体数据库_技术专栏:一篇文章搞懂晶体学信息文件CIF及其获取方法