完全匹配 待识别文字不能含有任何噪声 算法 f(p,size) 为从点p开始,大小为size的矩形块像素之和,这个函数使用查表法快速计算 字库:D 字的像素范围:m-M 字的大小范围:size_min-size_max 识别图像:src for each point in src: if f(p,size_max) M //像素太多 continue; //像素合适 for each w in D if f(p,w_size)==w_cnt ok=match(...) //作最后的匹配
| 1573 | end |
| 1574 | */ |
| 1575 | void ImageSearchAlgorithms::_bin_ocr(const Dictionary &dict, std::map<point_t, ocr_rec_t> &ps) { |
| 1576 | int px, py; |
| 1577 | if (_binary.empty()) |
| 1578 | return; |
| 1579 | // |
| 1580 | record_sum(_binary); |
| 1581 | // find cnt range |
| 1582 | // find width and height range; |
| 1583 | int cnt_min = 255 * 255, cnt_max = 0; |
| 1584 | int w_min = 255, h_min = 255; |
| 1585 | int w_max = 0, h_max = 0; |
| 1586 | for (auto &it : dict.words) { |
| 1587 | cnt_min = min(cnt_min, it.info.bit_cnt); |
| 1588 | cnt_max = max(cnt_max, it.info.bit_cnt); |
| 1589 | w_min = min(w_min, it.info.w); |
| 1590 | h_min = min(h_min, it.info.h); |
| 1591 | w_max = max(w_max, it.info.w); |
| 1592 | h_max = max(h_max, it.info.h); |
| 1593 | } |
| 1594 | |
| 1595 | // 将所有字库按照大小分成几类,对于每个大小根据像素密度查找对应的符合字库 |
| 1596 | auto makeinfo = [](int begin, int end, int szh, int szw) { |
| 1597 | return std::make_pair(begin << 16 | end, szh << 8 | szw); |
| 1598 | }; |
| 1599 | vector<std::pair<int, int>> dict_sz; |
| 1600 | auto &vword = dict.words; |
| 1601 | // 32 begin(8) |
| 1602 | dict_sz.push_back(makeinfo(0, 0, dict.words[0].info.h, dict.words[0].info.w)); |
| 1603 | for (size_t i = 1; i < vword.size(); ++i) { |
| 1604 | int sz = vword[i].info.h << 8 | vword[i].info.w; |
| 1605 | if (dict_sz.back().second != sz) { |
| 1606 | dict_sz.back().first |= static_cast<int>(i); // fix old end |
| 1607 | dict_sz.push_back(std::make_pair(static_cast<int>(i) << 16, sz)); // add new begin |
| 1608 | } |
| 1609 | } |
| 1610 | dict_sz.back().first |= static_cast<int>(vword.size()); |
| 1611 | |
| 1612 | // 遍历行 |
| 1613 | for (py = 0; py < _binary.height - h_min + 1; ++py) { |
| 1614 | // 遍历列 |
| 1615 | for (px = 0; px < _binary.width - w_min + 1; ++px) { |
| 1616 | if (_record.at(py, px)) |
| 1617 | continue; |
| 1618 | // 检测像素密度 |
| 1619 | if (region_sum(px, py, min(px + w_max, _binary.width), min(py + h_max, _binary.height)) < |
| 1620 | cnt_min) // too less |
| 1621 | continue; |
| 1622 | if (region_sum(px, py, px + w_min, py + h_min) > cnt_max) // too much |
| 1623 | continue; |
| 1624 | point_t pt; |
| 1625 | pt.x = px; |
| 1626 | pt.y = py; |
| 1627 | int k = 0; |
| 1628 | for (size_t k = 0; k < dict_sz.size(); ++k) { |
| 1629 | int h = dict_sz[k].second >> 8, w = dict_sz[k].second & 0xff; |
| 1630 | rect_t crc; |
| 1631 | crc.x1 = px; |
| 1632 | crc.y1 = py; |
nothing calls this directly
no test coverage detected