void Square::print() { std::cout << "Square:" << std::endl; std::cout << "Left-top point:" << std::endl; left_top().print(); std::cout << "Right-top point:" << std::endl; right_top().print(); std::cout << "Left-Bottom point:" << std::endl; left_bottom().print(); std::cout << "Right-bottom point:" << std::endl; right_bottom().print(); }
void DetectRegions::part2( const cv::Mat& input, std::vector<img_Plate>& output, cv::Mat& img_threshold, const std::string& out_id ) { cv::Mat my_input; input.copyTo(my_input); //Find contours of possibles plates std::vector< std::vector< cv::Point> > contours; findContours( img_threshold, contours, // a vector of contours CV_RETR_EXTERNAL, // retrieve the external contours // CV_CHAIN_APPROX_NONE ); // all pixels of each contours CV_CHAIN_APPROX_SIMPLE ); //Start to iterate to each contour founded std::vector< std::vector<cv::Point> >::iterator itc = contours.begin(); std::vector<cv::RotatedRect> rects; cv::Mat my_input_rect; input.copyTo(my_input_rect); //Remove patch that are no inside limits of aspect ratio and area. while (itc != contours.end()) { //Create bounding rect of object cv::RotatedRect mr = minAreaRect(cv::Mat(*itc)); if (!verifySizes(mr)) { itc = contours.erase(itc); // rotated rectangle drawing cv::Point2f rect_points[4]; mr.points( rect_points ); for (int j = 0; j < 4; ++j) line( my_input_rect, rect_points[j], rect_points[ (j + 1) % 4 ], cv::Scalar(255,0,0), 1, 8 ); } else { ++itc; rects.push_back(mr); // rotated rectangle drawing cv::Point2f rect_points[4]; mr.points( rect_points ); for (int j = 0; j < 4; ++j) line( my_input_rect, rect_points[j], rect_points[ (j + 1) % 4 ], cv::Scalar(0,255,0), 2, 8 ); } } D_IMG_SAVE( my_input_rect, "img_" << out_id << "Rect.png" ); // Draw blue contours on a white image cv::Mat result; input.copyTo(result); cv::drawContours( result, contours, -1, // draw all contours cv::Scalar(255,0,0), // in blue 1 ); // with a thickness of 1 // 3 ); // with a thickness of 1 D_IMG_SAVE( result, "04_img_" << out_id << "Contours.png" ); // std::cerr << "rects.size : " << rects.size() << std::endl; std::vector<cv::Mat> Mats; for (unsigned int i = 0; i < rects.size(); ++i) { //For better rect cropping for each posible box //Make floodfill algorithm because the plate has white background //And then we can retrieve more clearly the contour box circle(result, rects[i].center, 3, cv::Scalar(0,255,0), -1); //get the min size between width and height // float minSize = ( (rects[i].size.width < rects[i].size.height) float minSize = ( (rects[i].size.width > rects[i].size.height) ? (rects[i].size.width) : (rects[i].size.height) ); minSize = minSize - minSize * 0.5; //initialize rand and get 5 points around center for floodfill algorithm srand ( time(NULL) ); //Initialize floodfill parameters and variables cv::Mat mask; mask.create(input.rows + 2, input.cols + 2, CV_8UC1); mask = cv::Scalar::all(0); int loDiff = 30; int upDiff = 30; int connectivity = 4; int newMaskVal = 255; // int NumSeeds = 100; cv::Rect ccomp; int flags = connectivity + (newMaskVal << 8) + CV_FLOODFILL_FIXED_RANGE + CV_FLOODFILL_MASK_ONLY; int max_size = rects[i].size.width * rects[i].size.height; cv::Rect b_rect = rects[i].boundingRect(); int min_x = b_rect.x; int min_y = b_rect.y; int max_x = min_x + b_rect.width; int max_y = min_y + b_rect.height; for (int local_y = min_y; local_y < max_y; local_y += 5) for (int local_x = min_x; local_x < max_x; local_x += 5) { cv::Point seed; seed.x = local_x; seed.y = local_y; if (Collision( contours[i], seed )) { cv::Mat tmp_mask; tmp_mask.create( input.rows + 2, input.cols + 2, CV_8UC1 ); tmp_mask = cv::Scalar::all(0); int area = floodFill( input, tmp_mask, seed, cv::Scalar(255,0,0), &ccomp, cv::Scalar(loDiff, loDiff, loDiff), cv::Scalar(upDiff, upDiff, upDiff), flags ); { cv::Point c( ccomp.x + ccomp.width / 2, ccomp.y + ccomp.height / 2 ); cv::Size s( ccomp.width, ccomp.height ); cv::RotatedRect tmp_rect( c, s, 0 ); // rotated rectangle drawing cv::Point2f rect_points[4]; tmp_rect.points( rect_points ); for (int j = 0; j < 4; ++j) line( my_input, rect_points[j], rect_points[ (j + 1) % 4 ], cv::Scalar(0,255,255), 1, 8 ); } bool rect_invalid = ( ccomp.x < min_x || ccomp.x > max_x || ccomp.y < min_y || ccomp.y > max_y ); cv::Point left_top( min_x, min_y ); cv::Point right_top( max_x, min_y ); cv::Point left_bottom( min_x, max_y ); cv::Point right_bottom( max_x, max_y ); if (area > max_size) { circle( result, seed, 1, cv::Scalar(255,0,0), -1 ); circle( my_input, seed, 1, cv::Scalar(255,0,0), -1 ); } else if (rect_invalid) { circle( result, seed, 1, cv::Scalar(255,0,0), -1 ); circle( my_input, seed, 1, cv::Scalar(255,0,0), -1 ); } else { circle( result, seed, 1, cv::Scalar(0,255,0), -1 ); circle( my_input, seed, 1, cv::Scalar(0,255,0), -1 ); floodFill( input, mask, seed, cv::Scalar(255,0,0), &ccomp, cv::Scalar(loDiff, loDiff, loDiff), cv::Scalar(upDiff, upDiff, upDiff), flags ); } } else { circle( result, seed, 1, cv::Scalar(255,0,0), -1 ); circle( my_input, seed, 1, cv::Scalar(255,0,0), -1 ); } } // for (int j = 0; j < NumSeeds; ++j) { // rotated rectangle drawing cv::Point2f rect_points[4]; rects[i].points( rect_points ); for (int j = 0; j < 4; ++j) line( my_input, rect_points[j], rect_points[ (j + 1) % 4 ], cv::Scalar(255,255,255), 2, 8 ); D_IMG_SAVE( mask, "img_" << out_id << "" << i << "_01_Mask.png" ); } //cvWaitKey(0); //Check new floodfill mask match for a correct patch. //Get all points detected for get Minimal rotated Rect std::vector<cv::Point> pointsInterest; cv::Mat_<uchar>::iterator itMask = mask.begin<uchar>(); cv::Mat_<uchar>::iterator end = mask.end<uchar>(); for (; itMask != end; ++itMask) if (*itMask == 255) pointsInterest.push_back(itMask.pos()); if (pointsInterest.size() < 2) continue; cv::RotatedRect minRect = minAreaRect(pointsInterest); if (verifySizes(minRect)) { // rotated rectangle drawing cv::Point2f rect_points[4]; minRect.points( rect_points ); for( int j = 0; j < 4; j++ ) line( result, rect_points[j], rect_points[(j+1)%4], cv::Scalar(0,0,255), 1, 8 ); //Get rotation matrix float r = (float)minRect.size.width / (float)minRect.size.height; float angle=minRect.angle; if (r < 1) angle = 90 + angle; cv::Mat rotmat = getRotationMatrix2D(minRect.center, angle,1); //Create and rotate image cv::Mat img_rotated; warpAffine(input, img_rotated, rotmat, input.size(), CV_INTER_CUBIC); //Crop image cv::Size rect_size = minRect.size; if (r < 1) std::swap( rect_size.width, rect_size.height ); cv::Mat img_crop; getRectSubPix(img_rotated, rect_size, minRect.center, img_crop); D_IMG_SAVE( img_crop, "img_" << out_id << "" << i << "_02_crop.png" ); cv::Mat resultResized; resultResized.create(33,144, CV_8UC3); resize(img_crop, resultResized, resultResized.size(), 0, 0, cv::INTER_CUBIC); D_IMG_SAVE( resultResized, "img_" << out_id << "" << i << "_03_resultResized.png" ); output.push_back( img_Plate( resultResized, minRect.boundingRect() ) ); // //Equalize croped image // cv::Mat grayResult; // cvtColor(resultResized, grayResult, CV_BGR2GRAY); // // blur(grayResult, grayResult, Size(3,3)); // grayResult = histeq(grayResult); // D_IMG_SAVE( grayResult, "img_" << out_id << "" << i << "_04_grayResult.png" ); // output.push_back( Plate( grayResult, minRect.boundingRect() ) ); } // if (verifySizes(minRect)) } // for (int i = 0; i < rects.size(); ++i) D_IMG_SAVE( result, "10_img_" << out_id << "Contours.png" ); D_IMG_SAVE( my_input, "11_img_" << out_id << "my_input.png" ); }
void SpaceTranformWindow::transformImage() { _DataTransformed = std::make_shared<QImage> (_DataHandled.size(),_DataHandled.format()); int width = _DataHandled.width(); int height = _DataHandled.height(); int width_half = width/2; int height_half = height/2; double sinAngle = sin(_TransformAngle); double cosAngle = cos(_TransformAngle); int move_width_temp =static_cast<int>(_DataHandled.width()* (static_cast<double>(_VectorMove.x())/ui->ShowImage->width())) /(_Scale_vertical*_Scale_width_ShowImage); int move_height_temp = static_cast<int>(_DataHandled.height()* (static_cast<double>(_VectorMove.y())/ui->ShowImage->height())) /(_Scale_horizontal*_Scale_height_ShowImage); int move_width = move_width_temp; int move_height = move_height_temp; double origin_x,origin_y; //-2:邻近,-3:双线性 if(_TransformMode.checkedId() == -2) { for(int i=0;i<width;++i) { for(int j=0;j<height;++j) { origin_x =i; origin_y =j; /*平移还原*/ origin_x -=move_width; origin_y -=move_height; /*缩放还原*/ origin_x = static_cast<double>(origin_x - _TransformCenter.x()) /(_Scale_vertical*_Scale_width_ShowImage) + _TransformCenter.x(); origin_y = static_cast<double>(origin_y - _TransformCenter.y()) /(_Scale_horizontal*_Scale_height_ShowImage) + _TransformCenter.y(); /*旋转还原*/ double temp = origin_x; origin_x = (origin_x-width_half)*cosAngle+(origin_y-height_half)*sinAngle +width_half; origin_y = (origin_y-height_half)*cosAngle-(temp-width_half)*sinAngle +height_half; int x=round(origin_x); int y=round(origin_y); if(x<width&&x>=0&& y<height&&y>=0) { _DataTransformed->setPixel(i,j,_DataHandled.pixel(x,y)); } } } } else if(_TransformMode.checkedId() == -3) { for(int i=0;i<width;++i) { for(int j=0;j<height;++j) { origin_x =i; origin_y =j; /*平移还原*/ origin_x -=move_width; origin_y -=move_height; /*缩放还原*/ origin_x = static_cast<double>(origin_x - _TransformCenter.x()) /(_Scale_vertical*_Scale_width_ShowImage) + _TransformCenter.x(); origin_y = static_cast<double>(origin_y - _TransformCenter.y()) /(_Scale_horizontal*_Scale_height_ShowImage) + _TransformCenter.y(); /*旋转还原*/ double temp = origin_x; origin_x = (origin_x-width_half)*cosAngle+(origin_y-height_half)*sinAngle +width_half; origin_y = (origin_y-height_half)*cosAngle-(temp-width_half)*sinAngle +height_half; QPoint left_top(floor(origin_x),floor(origin_y)); QPoint right_top(ceil(origin_x),floor(origin_y)); QPoint left_bottom(floor(origin_x),ceil(origin_y)); QPoint right_bottom(ceil(origin_x),ceil(origin_y)); if( left_top.x()<width&&left_top.y()<height&& left_top.x()>=0&&left_top.y()>=0&& right_top.x()<width&&right_top.y()<height&& right_top.x()>=0&&right_top.y()>=0&& left_bottom.x()<width&&left_bottom.y()<height&& left_bottom.x()>=0&&left_bottom.y()>=0&& right_bottom.x()<width&&right_bottom.y()<height&& right_bottom.x()>=0&&right_bottom.y()>=0 ) { /* * 00 10 * xy * * 01 11 * */ QColor p_0_0(_DataHandled.pixel(left_top.x(),left_top.y())); QColor p_1_0(_DataHandled.pixel(right_top.x(),right_top.y())); QColor p_0_1(_DataHandled.pixel(left_bottom.x(),left_bottom.y())); QColor p_1_1(_DataHandled.pixel(right_bottom.x(),right_bottom.y())); /* * f(x,0) =f(0,0)+x[f(1,0)-f(0,0)] * f(x,1) =f(0,1)+x[f(1,1)-f(0,1)] * f(x,y) =f(x,0)+y[f(x,1)-f(x,0)] */ auto red = p_0_0.red() + (origin_x - left_top.x())*(p_1_0.red() - p_0_0.red()) + (origin_y - left_top.y())* ((p_0_1.red() +(origin_x - left_top.x())*(p_1_1.red() - p_0_1.red()))- (p_0_0.red() + (origin_x - left_top.x())*(p_1_0.red() - p_0_0.red()))); auto green = p_0_0.green() + (origin_x - left_top.x())*(p_1_0.green() - p_0_0.green()) + (origin_y - left_top.y())* ((p_0_1.green() +(origin_x - left_top.x())*(p_1_1.green() - p_0_1.green()))- (p_0_0.green() + (origin_x - left_top.x())*(p_1_0.green() - p_0_0.green()))); auto blue = p_0_0.blue() + (origin_x - left_top.x())*(p_1_0.blue() - p_0_0.blue()) + (origin_y - left_top.y())* ((p_0_1.blue() +(origin_x - left_top.x())*(p_1_1.blue() - p_0_1.blue())) - (p_0_0.blue() + (origin_x - left_top.x())*(p_1_0.blue() - p_0_0.blue()))); QColor newColor(red,green,blue); _DataTransformed->setPixel(i,j,newColor.rgb()); } } } } else { //do nothing } showImage(*_DataTransformed,ui->ShowImage); }