/** * Find and isolate the digits of the counter, */ void ImageProcessor::findCounterDigits() { log4cpp::Category& rlog = log4cpp::Category::getRoot(); // edge image cv::Mat edges = cannyEdges(); if (_debugEdges) { cv::imshow("edges", edges); } cv::Mat img_ret = edges.clone(); // find contours in whole image std::vector<std::vector<cv::Point> > contours, filteredContours; std::vector<cv::Rect> boundingBoxes; cv::findContours(edges, contours, CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE); // filter contours by bounding rect size filterContours(contours, boundingBoxes, filteredContours); rlog << log4cpp::Priority::INFO << "number of filtered contours: " << filteredContours.size(); // find bounding boxes that are aligned at y position std::vector<cv::Rect> alignedBoundingBoxes, tmpRes; for (std::vector<cv::Rect>::const_iterator ib = boundingBoxes.begin(); ib != boundingBoxes.end(); ++ib) { tmpRes.clear(); findAlignedBoxes(ib, boundingBoxes.end(), tmpRes); if (tmpRes.size() > alignedBoundingBoxes.size()) { alignedBoundingBoxes = tmpRes; } } rlog << log4cpp::Priority::INFO << "max number of alignedBoxes: " << alignedBoundingBoxes.size(); // sort bounding boxes from left to right std::sort(alignedBoundingBoxes.begin(), alignedBoundingBoxes.end(), sortRectByX()); if (_debugEdges) { // draw contours cv::Mat cont = cv::Mat::zeros(edges.rows, edges.cols, CV_8UC1); cv::drawContours(cont, filteredContours, -1, cv::Scalar(255)); cv::imshow("contours", cont); } // cut out found rectangles from edged image for (int i = 0; i < alignedBoundingBoxes.size(); ++i) { cv::Rect roi = alignedBoundingBoxes[i]; _digits.push_back(img_ret(roi)); if (_debugDigits) { cv::rectangle(_img, roi, cv::Scalar(0, 255, 0), 2); } } }
/** * Detect the skew of the image by finding almost (+- 30 deg) horizontal lines. */ float ImageProcessor::detectSkew() { log4cpp::Category& rlog = log4cpp::Category::getRoot(); cv::Mat edges = cannyEdges(); // find lines std::vector<cv::Vec2f> lines; cv::HoughLines(edges, lines, 1, CV_PI / 180.f, 140); // filter lines by theta and compute average std::vector<cv::Vec2f> filteredLines; float theta_min = 60.f * CV_PI / 180.f; float theta_max = 120.f * CV_PI / 180.0f; float theta_avr = 0.f; float theta_deg = 0.f; for (size_t i = 0; i < lines.size(); i++) { float theta = lines[i][1]; if (theta >= theta_min && theta <= theta_max) { filteredLines.push_back(lines[i]); theta_avr += theta; } } if (filteredLines.size() > 0) { theta_avr /= filteredLines.size(); theta_deg = (theta_avr / CV_PI * 180.f) - 90; rlog.info("detectSkew: %.1f deg", theta_deg); } else { rlog.warn("failed to detect skew"); } if (_debugSkew) { drawLines(filteredLines); } return theta_deg; }
void KMAcomputeShape(const boost_math::double_matrix &patch_lcpos, const boost_math::double_matrix &patch_lrpos, DARY *img, vector<float> &vec) { const int _ShapeSize = kma::shape::SrSize * kma::shape::ScSize * kma::shape::SOriSize; assert((int)vec.size() == _ShapeSize); uint patch_width = PATCH_SIZE; uint patch_height = PATCH_SIZE; assert(img->x() == patch_width && img->y() == patch_height); assert(patch_lcpos.size1() == patch_height && patch_lcpos.size2() == patch_width); assert(patch_lrpos.size1() == patch_height && patch_lrpos.size2() == patch_width); int oriSize = kma::shape::SOriSize; int rSize = kma::shape::SrSize; int cSize = kma::shape::ScSize; DARY *grad = new DARY(PATCH_SIZE,PATCH_SIZE); DARY *ori = new DARY(PATCH_SIZE,PATCH_SIZE); DARY *dx = new DARY(img->y(),img->x()); DARY *dy = new DARY(img->y(),img->x()); DARY *edge = new DARY(img->y(),img->x()); dX2(img,dx); dY2(img,dy); for(uint j=0;j<grad->y();j++){ for(uint i=0;i<grad->x();i++){ grad->fel[j][i]=sqrt(dx->fel[j][i]*dx->fel[j][i]+dy->fel[j][i]*dy->fel[j][i]); ori->fel[j][i]=atan2(dy->fel[j][i],dx->fel[j][i]); } } /* initialize edge image */ memset(edge->fel[0], 0, edge->x()*edge->y()*sizeof(float)); cannyEdges(dx, dy, grad, edge, 5, 15); delete dx; delete dy; delete grad; /* begin of KeyLogPolSample(vec, edge, ori, angle, SOriSize, SrSize, ScSize); */ int iradius = (int)floor(PATCH_SIZE/2); for (int i = -iradius; i <= iradius; i++) for (int j = -iradius; j <= iradius; j++) { // lcpos=(M_PI+atan2(rpos,cpos))*cspacing; // lrpos=log(1+sqrt((float)i*i+j*j)/iradius)*rSize; double lcpos = patch_lcpos(iradius + j, iradius + i); double lrpos = patch_lrpos(iradius + j, iradius + i); double rx = lrpos;// + (rSize - 1) / 2.0; double cx = lcpos;// + (cSize - 1) / 2.0; if (rx > -1.0 && rx < (float) rSize && cx > -1.0 && cx < (float) cSize) { //cout << "in" << cpos << " " << rpos << endl; KMAAddLogPolSample(vec, edge, ori, 0.0, iradius + i, iradius + j, lrpos, lcpos, /* not used ? */ lrpos, lcpos, /* rx, cx */ oriSize, rSize, cSize); } } /* end of KeyLogPolSample */ delete edge; delete ori; KMANormalizeVect(vec); int intval, changed = FALSE; //for (int i = 0; i < kma::shape::ShapeSize; i++) for (int i = 0; i < _ShapeSize; i++) if (vec[i] > kma::shape::MaxIndexVal) { vec[i] = kma::shape::MaxIndexVal; changed = TRUE; } if (changed) { KMANormalizeVect(vec); } /* Convert float vector to integer. Assume largest value in normalized vector is likely to be less than 0.5. */ //for (int i = 0; i < kma::shape::ShapeSize; i++) { for (int i = 0; i < _ShapeSize; i++) { intval = (int) (512.0 * vec[i]); vec[i] = (255 < intval) ? 255 : intval; } }