/** * Takes a 3d plane and draws its transform on the given image. */ void TableObjectDetector::drawTablePlane(Mat img, Mat* plane, KinectCalibParams* calib) { Point pt[1][4]; Mat R = calib->getR(); Mat Rt; transpose(R, Rt); Mat T = calib->getT(); Mat K = calib->getRGBIntrinsics(); for (int i=0; i<4; i++) { Mat p = plane->col(i+1); // Apply extrinsics Mat prgbw = Rt*p - T; // Calculate transform to RGB plane Mat prgb_hat = K*prgbw; Point prgb((int)(prgb_hat.at<double>(0)/prgb_hat.at<double>(2)), (int)(prgb_hat.at<double>(1)/prgb_hat.at<double>(2))); pt[0][i] = prgb; } const Point* ppt[1] = {pt[0]}; int npt[] = {4}; fillPoly(img, ppt, npt, 1, Scalar(255, 0, 255), 8); }
void BodyModel::drawTriangle(Point p1, Point p2, Point p3) { Point rook_points[1][3]; rook_points[0][0] = p1; rook_points[0][1] = p2; rook_points[0][2] = p3; const Point* ppt[1] = { rook_points[0] }; int npt[] = { 3 }; fillPoly(_mask, ppt, npt, 1, Scalar(255, 255, 255), 8); }
void BodyModel::drawPolygon(Point upperRight, Point upperLeft, Point lowerRight, Point lowerLeft) { Point rook_points[1][4]; rook_points[0][0] = upperRight; rook_points[0][3] = upperLeft; rook_points[0][1] = lowerRight; rook_points[0][2] = lowerLeft; const Point* ppt[1] = { rook_points[0] }; int npt[] = { 4 }; fillPoly(_mask, ppt, npt, 1, Scalar(255, 255, 255), 8); }
void drawPolyPoints() { int n = poly_points.size(); int npt[] = { n }; /** Create some points */ cv::Point **points = new cv::Point*[1]; points[0]=new cv::Point[n]; for (int i=0; i<n; i++) { points[0][i] = poly_points[i]; } const cv::Point* ppt[1] = { points[0] }; fillPoly( grid, ppt, npt, 1, pen_color, line_type); delete [] points[0]; delete [] points; }
void BodyModel::drawBodyShape(Point upperRight, Point upperLeft, Point lowerRight, Point lowerLeft, int max) { Point rook_points[1][8]; rook_points[0][0] = upperRight; rook_points[0][7] = upperLeft; rook_points[0][3] = lowerRight; rook_points[0][4] = lowerLeft; rook_points[0][2] = ( upperRight + lowerRight ) / 2; rook_points[0][1] = ( upperRight + rook_points[0][2] ) / 2 + Point(max, - 2 * abs(max)); rook_points[0][5] = ( upperLeft + lowerLeft ) / 2; rook_points[0][6] = ( upperLeft + rook_points[0][5] ) / 2 + Point(- max, 0); const Point* ppt[1] = { rook_points[0] }; int npt[] = { 8 }; fillPoly(_mask, ppt, npt, 1, Scalar(255, 255, 255), 8); }
// === FUNCTION ====================================================================== // Name: get_masked_frame // Description: Masks the frame based on slope and roi. Mask returned by pointer. // ===================================================================================== cv::Mat get_masked_frame ( cv::Rect roi, double slope, cv::Mat* frame, cv::Mat* mask ) { cv::Point corners[1][4]; //Set the frame *mask=cv::Mat::zeros( frame->size(), CV_8UC1 ); cv::Mat masked_frame; if( slope==0 ) { // TODO: Could use direction handling here. corners[0][0] = roi.br(); corners[0][1] = cv::Point( frame->cols, roi.y+roi.height ); corners[0][2] = corners[0][1]-cv::Point( 0, roi.height ); corners[0][3] = corners[0][0]-cv::Point( 0, roi.height ); } else if( isinf( slope ) ) { { corners[0][0] = cv::Point( roi.x, frame->rows ); corners[0][1] = cv::Point( roi.x, roi.y+roi.height); } { corners[0][0] = roi.tl(); corners[0][1] = cv::Point( roi.x, 0 ); } corners[0][2] = corners[0][1]+cv::Point( roi.width, 0); corners[0][3] = corners[0][0]+cv::Point( roi.width, 0 ); } else { corners[0][0].x = ( int ) ( (frame->rows + slope*roi.x-roi.y)/slope ); corners[0][0].y = frame->rows; corners[0][1] = cv::Point( ( int )( (-roi.y + slope * roi.x ) / slope ), 0 ); corners[0][2] = corners[0][1] + cv::Point(roi.width, 0); corners[0][3] = corners[0][0] + cv::Point(roi.width, 0); } // This is weird, but follows OpenCV docs. const cv::Point* ppt[1] = { corners[0] }; const int npt[] = { 4 }; fillPoly( *mask, ppt, npt, 1, 255 ); frame->copyTo(masked_frame, *mask); return masked_frame; } // ----- end of function get_masked_frame -----
void RoadDetection::drawRoadShape(Mat frame, vector<Point> points, Scalar color, double alpha) { Mat copy; Point shapePoints[1][3]; int npt[] = { 3 }; if (points.size() <= 0) { return; } for (size_t i = 0; i < points.size(); i++) { shapePoints[0][i] = points[i]; } const Point* ppt[1] = { shapePoints[0] }; frame.copyTo(copy); fillPoly(copy, ppt, npt, 1, color, CV_AA); addWeighted(copy, alpha, frame, 1.0 - alpha, 0.0, frame); }
void FieldLineDetector::createThresholdedImg(Mat& src) { vector<vector<cv::Point> > cont; vector<vector<cv::Point> > contPoly; vector<Vec4i> hierarchy; Mat imgBwInv; imgThres = threshold(src); // find large contours and remove them from thresholded image bitwise_not(imgThres, imgBwInv); findContours(imgBwInv, cont, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, cv::Point(0, 0)); for (int i = 0; i < cont.size(); i++) { double area = contourArea(cont[i]); if (area > 100000) { contPoly.push_back(cont[i]); } } fillPoly(imgThres, contPoly, Scalar(255, 255, 255)); imshow("thres", imgThres); }
void drawTriangle(int mx, int my, int x, int y, Mat img){ int thickness = 1; int lineType = 8; int wide = WIDE/mx; int height = HEIGHT/my; Point center=getCenter(mx,my,x,y); /** Create some points */ Point rook_points[1][3]; rook_points[0][0] = Point( center.x, center.y-(height/2-5) ); rook_points[0][1] = Point( center.x-(wide/2-5), center.y+(height/2-5) ); rook_points[0][2] = Point( center.x+(wide/2-5), center.y+(height/2-5) ); const Point* ppt[1] = { rook_points[0] }; int npt[] = { 3 }; fillPoly( img, ppt, npt, thickness, Scalar( 255, 255, 255 ), lineType ); }
void ModelMaker::extractModel(cv::Mat origframe) { // qDebug()<<"Frame is"<<frame.empty(); for(int i = 0; i < centroids.size(); i++) { Mat subtractedframe(origframe); subtractedframe = subtractBack(origframe); Mat polymask = subtractedframe.clone(); // cv::cvtColor(frameMat, frameMat, CV_BGR2BGRA); // cv::cvtColor(polymask, polymask, CV_BGR2BGRA); //cv::rectangle(mask, Point( 0, 0 ), Point( mask.cols, mask.rows), Scalar( 0, 255,0,255 ),-1, 8 ); //Fill all mask in polymask.setTo(Scalar(0,0,0,0)); //Polgon Masking polygon = paintCanvas->polygons.at(i); Point poly_points[polygon.size()]; //Find point furthest from center Point furthest = Point(paintCanvas->centerPoint.x()*xscale,paintCanvas->centerPoint.y()*yscale); //set to center int scaledcenterx = paintCanvas->centerPoint.x()*xscale; int scaledcentery = paintCanvas->centerPoint.y()*yscale; int scaledheadx= paintCanvas->headPoint.x()*xscale; int scaledheady=paintCanvas->headPoint.y()*yscale; float biggestdistancesquared=0; for(int j=0;j<polygon.size();j++) { poly_points[j]=Point(xscale*polygon.at(j).x(), yscale*polygon.at(j).y()); Point candidate = Point(xscale*polygon.at(j).x(), yscale*polygon.at(j).y()); float distancecandidatesquared; //Find furthest distancecandidatesquared= (candidate.x - scaledcenterx)*(candidate.x - scaledcenterx) + (candidate.y - scaledcentery)*(candidate.y - scaledcentery); if(distancecandidatesquared>biggestdistancesquared){ biggestdistancesquared=distancecandidatesquared; qDebug()<<"biggcandidate x "<<candidate.x <<" y "<<candidate.y << " distance ="<<biggestdistancesquared; } } const Point* ppt[1] = { poly_points }; int npt[] = { polygon.size() }; fillPoly( polymask, ppt, npt, 1, Scalar( 255, 255,255,255 ), 8, 0); //Debug // cv::circle(origframe,cv::Point(scaledcenterx,scaledcentery),1,Scalar(255,255,255,255),2); // cv::circle(origframe,cv::Point(scaledheadx,scaledheady),1,Scalar(255,0,255, 254),2); //cv::circle(polymask,cv::Point(scaledcenterx,scaledcentery),1,Scalar(255,255,255,255),2); // cv::circle(polymask,cv::Point(scaledheadx,scaledheady),1,Scalar(255,0,255, 254),2); // cv::circle(subtractedframe,cv::Point(scaledcenterx,scaledcentery),1,Scalar(255,255,255,255),2); // cv::circle(subtractedframe,cv::Point(scaledheadx,scaledheady),1,Scalar(255,0,255, 254),2); //background subtraction: take original image, apply background as a mask, save over original //bitwise_and(subtractedframe, polymask, subtractedframe); qDebug()<<"Roi "<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<" "; cv::cvtColor(polymask,polymask, CV_RGB2GRAY); //Full alpha mask = polygon selection (a =200) + BG subtracted organism (a= 255) + Center Mark ( a = 250) + head mark (a = 240) //Set Head to alpha=240 //Set Center to Alpha = 250 //Everything inside mask == alpha 200 //Everything outside alpha=100; //BG subtracted ant = 255 Mat maskedsubtraction; subtractedframe.copyTo(maskedsubtraction,polymask); // note that m.copyTo(m,mask) will have no masking effect cvtColor(maskedsubtraction, maskedsubtraction,CV_BGR2GRAY); polymask = polymask+155; //255 moves to 255, 0 moves to 155 polymask = polymask - 55; //255 moves to 200, 155 moves to 100 maskedsubtraction = polymask+maskedsubtraction; cv::circle(maskedsubtraction,cv::Point(scaledcenterx,scaledcentery),1,Scalar(250),2); //Encode the Center cv::circle(maskedsubtraction,cv::Point(scaledheadx,scaledheady),1,Scalar(240),2); //encode the head Mat bgr; bgr=origframe.clone(); Mat alpha; maskedsubtraction.copyTo(alpha); Mat bgra; cvtColor(origframe, bgra,CV_BGR2BGRA); //Copy the origframe, we'll write over it next // forming array of matrices is quite efficient operations, // because the matrix data is not copied, only the headers Mat in[] = { bgr, alpha }; // BGRa[0] -> bgr[0], BGRa[1] -> bgr[1], // BGRa[2] -> bgr[2], BGRa[3] -> alpha[0] int from_to[] = { 0,0, 1,1, 2,2, 3,3 }; mixChannels( in, 2, &bgra, 1, from_to, 4 ); // input array, number of files in input array, destination, number of files in destination, from-to array, number of pairs in from-to QString ext = ".png"; // QString fullframe = savepath+paintCanvas->polyNames.at(i)+"_"+QString::number(centroids[i].x())+"_"+QString::number(centroids[i].y())+"_"+QString::number(currentFrame)+ext; QString modelfilename = savepath+paintCanvas->polyNames.at(i)+"_f"+QString::number(currentFrame)+ext; //DEBUG IMAGES /* imwrite(modelfilename.toStdString()+"_subtraction",subtractedframe); imwrite(modelfilename.toStdString()+"_polymask",polymask); imwrite(modelfilename.toStdString()+"_alpha",alpha); */ //save out Model //Full Keyframe // imwrite(modelfilename.toStdString()+"_keyframe",bgra); //Disabled for now qDebug()<<"Saved out: "<<modelfilename; //***Crop and Rotate ***// qDebug()<<"crop centered on "<<scaledcenterx<<" "<<scaledcentery; //crop the frame based on ROI Point2f src_center(scaledcenterx, scaledcentery); //To do this correctly use getRectSubPix instead of frameMat(MYROI) method // getRectSubPix only works with certain image formats (this is undocumented in opencv : P // so we have to do that cutting and mixing again! getRectSubPix(bgr, cv::Size(sqrt(biggestdistancesquared)*2,sqrt(biggestdistancesquared)*2), src_center, bgr); getRectSubPix(alpha, cv::Size(sqrt(biggestdistancesquared)*2,sqrt(biggestdistancesquared)*2), src_center, alpha); Mat bgracropped; cvtColor(bgr, bgracropped,CV_BGR2BGRA); //Copy the origframe, we'll write over it next Mat inagain[] = { bgr, alpha }; int from_to2[] = { 0,0, 1,1, 2,2, 3,3 }; //Note: the height and width dimensions have to be the same for the inputs and outputs mixChannels( inagain, 2, &bgracropped, 1, from_to2, 4 ); // input array, number of files in input array, destination, number of files in destination, from-to array, number of pairs in from-to //rotate the cropped frame about the center of the cropped frame. qDebug()<<"Rotate that image "<<angle; bgracropped = rotateImage(bgracropped, angle);//Rotate full image about this center //after I rotate clear the global angle angle =0; //debug angle=-1; // Save the Nicely Rotated and Cropped Model File imwrite(modelfilename.toStdString(),bgracropped); centroids.clear(); maxXY.clear(); minXY.clear(); paintCanvas->polyNames.clear(); paintCanvas->polygons.clear(); paintCanvas->masks.pop_back(); polyinfo = "Polygon cleared"; paintCanvas->temp.clear(); ui->statusBar->showMessage(polyinfo,2000); paintCanvas->replyMask = replyNull; capture.set(CV_CAP_PROP_POS_FRAMES,(double)currentFrame); } }
Scalar refineSegments(const Mat& img, Mat& mask, Mat& dst, vector<Point>& contour, vector<Point>& second_contour, Point2i& previous) { // int niters = 3; vector<vector<Point> > contours; vector<Vec4i> hierarchy; Mat temp; blur(mask, temp, Size(11,11)); temp = temp > 85.0; findContours( temp, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE ); if(dst.data==NULL) dst = Mat::zeros(img.size(), CV_8UC1); else dst.setTo(Scalar(0)); if( contours.size() == 0 ) return Scalar(-1,-1); // iterate through all the top-level contours, // draw each connected component with its own random color int idx = 0, largestComp = -1, secondlargest = -1; double maxWArea = 0, maxJArea = 0; vector<double> justarea(contours.size()); vector<double> weightedarea(contours.size()); // for( ; idx >= 0; idx = hierarchy[idx][0] ) for (; idx<contours.size(); idx++) { const vector<Point>& c = contours[idx]; Scalar _mean = mean(Mat(contours[idx])); justarea[idx] = fabs(contourArea(Mat(c))); weightedarea[idx] = fabs(contourArea(Mat(c))) / ((previous.x >- 1) ? (1.0 + norm(Point(_mean[0],_mean[1])-previous)) : 1.0); //consider distance from last blob } for (idx = 0; idx<contours.size(); idx++) { if( weightedarea[idx] > maxWArea ) { maxWArea = weightedarea[idx]; largestComp = idx; } } for (idx = 0; idx < contours.size(); idx++) { if ( justarea[idx] > maxJArea && idx != largestComp ) { maxJArea = justarea[idx]; secondlargest = idx; } } Scalar color( 255 ); // cout << "largest cc " << largestComp << endl; // drawContours( dst, contours, largestComp, color, CV_FILLED); //, 8, hierarchy ); // for (idx=0; idx<contours[largestComp].size()-1; idx++) { // line(dst, contours[largestComp][idx], contours[largestComp][idx+1], color, 2); // if(largestComp >= 0) { //find top-left values int maxx = -INT_MAX,miny = INT_MAX; int num = contours[largestComp].size(); for (int i=0; i<num; i++) { if(contours[largestComp][i].x > maxx) maxx = contours[largestComp][i].x; if(contours[largestComp][i].y < miny) miny = contours[largestComp][i].y; } //crop contour to 150x150 "window" vector<Point> newblob = contours[largestComp]; // int maxxp150 = MAX(maxx-200,0),minyp150 = MIN(miny+170,480); // // for (int i=0; i<num; i++) { // Point _p = contours[largestComp][i]; // if(_p.x > maxxp150 && _p.y < minyp150) newblob.push_back(_p); // else newblob.push_back(Point(MAX(_p.x,maxxp150),MIN(_p.y,minyp150))); // } Point* pts = &(newblob[0]); num = newblob.size(); fillPoly(dst, (const Point**)(&pts), &num, 1, color); Scalar b = mean(Mat(newblob)); //center of the blob b[0] += 40; b[1] -= 40; b[2] = justarea[largestComp]; contour.clear(); contour = newblob; second_contour.clear(); if(secondlargest >= 0) { second_contour = contours[secondlargest]; b[3] = maxJArea; } previous.x = b[0]; previous.y = b[1]; return b; } else return Scalar(-1,-1); }
void PlateLines::processImage(Mat inputImage, vector<TextLine> textLines, float sensitivity) { if (this->debug) cout << "PlateLines findLines" << endl; timespec startTime; getTimeMonotonic(&startTime); // Ignore input images that are pure white or pure black Scalar avgPixelIntensity = mean(inputImage); if (avgPixelIntensity[0] >= 252) return; else if (avgPixelIntensity[0] <= 3) return; // Do a bilateral filter to clean the noise but keep edges sharp Mat smoothed(inputImage.size(), inputImage.type()); adaptiveBilateralFilter(inputImage, smoothed, Size(3,3), 45, 45); int morph_elem = 2; int morph_size = 2; Mat element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) ); Mat edges(inputImage.size(), inputImage.type()); Canny(smoothed, edges, 66, 133); // Create a mask that is dilated based on the detected characters Mat mask = Mat::zeros(inputImage.size(), CV_8U); for (unsigned int i = 0; i < textLines.size(); i++) { vector<vector<Point> > polygons; polygons.push_back(textLines[i].textArea); fillPoly(mask, polygons, Scalar(255,255,255)); } dilate(mask, mask, getStructuringElement( 1, Size( 1 + 1, 2*1+1 ), Point( 1, 1 ) )); bitwise_not(mask, mask); // AND canny edges with the character mask bitwise_and(edges, mask, edges); vector<PlateLine> hlines = this->getLines(edges, sensitivity, false); vector<PlateLine> vlines = this->getLines(edges, sensitivity, true); for (unsigned int i = 0; i < hlines.size(); i++) this->horizontalLines.push_back(hlines[i]); for (unsigned int i = 0; i < vlines.size(); i++) this->verticalLines.push_back(vlines[i]); // if debug is enabled, draw the image if (this->debug) { Mat debugImgHoriz(edges.size(), edges.type()); Mat debugImgVert(edges.size(), edges.type()); edges.copyTo(debugImgHoriz); edges.copyTo(debugImgVert); cvtColor(debugImgHoriz,debugImgHoriz,CV_GRAY2BGR); cvtColor(debugImgVert,debugImgVert,CV_GRAY2BGR); for( size_t i = 0; i < this->horizontalLines.size(); i++ ) { line( debugImgHoriz, this->horizontalLines[i].line.p1, this->horizontalLines[i].line.p2, Scalar(0,0,255), 1, CV_AA); } for( size_t i = 0; i < this->verticalLines.size(); i++ ) { line( debugImgVert, this->verticalLines[i].line.p1, this->verticalLines[i].line.p2, Scalar(0,0,255), 1, CV_AA); } vector<Mat> images; images.push_back(debugImgHoriz); images.push_back(debugImgVert); Mat dashboard = drawImageDashboard(images, debugImgVert.type(), 1); displayImage(pipelineData->config, "Hough Lines", dashboard); } if (pipelineData->config->debugTiming) { timespec endTime; getTimeMonotonic(&endTime); cout << "Plate Lines Time: " << diffclock(startTime, endTime) << "ms." << endl; } }
void MainWindow::mouseHandler(int event, int x, int y, int flags, void* param) { MainWindow* window = (MainWindow*) param; if (window->mode == 3) { x = bound(x, window->R, window->_src.cols-1-window->R); y = bound(y, window->R, window->_src.rows-1-window->R); } else { x = bound(x, 0, window->_src.cols-1); y = bound(y, 0, window->_src.rows-1); } // user press left button if (event == CV_EVENT_LBUTTONDOWN && !window->drag) { if (window->mode == 1) window->point = Point(x, y); else if (window->mode == 2) { window->points.clear(); window->points.push_back(Point(x, y)); } else if (window->mode == 3) { Rect box = Rect(x-window->R, y-window->R, 1+window->R*2, 1+window->R*2); Mat temp; medianBlur(window->_dst(box), temp, window->kernel); temp.copyTo(window->_dst(box), window->round_mask); window->round_mask.copyTo(window->zone(box), window->round_mask); imshow("Image", window->_dst); } window->drag = true; } // user drag the mouse if (event == CV_EVENT_MOUSEMOVE && window->drag) { Mat temp = window->_dst.clone(); if (window->mode == 1) rectangle(temp, window->point, Point(x, y), CV_RGB(255, 0, 0), 2, 8, 0); else if (window->mode == 2) { window->pts = (const Point*)Mat(window->points).data; window->npts = window->points.size(); window->points.push_back(Point(x, y)); polylines(temp, &window->pts, &window->npts, 1, false, Scalar(0,0,255), 2, 8, 0); } else if (window->mode == 3) { Rect box = Rect(x-window->R, y-window->R, 1+window->R*2, 1+window->R*2); Mat temp; medianBlur(window->_dst(box), temp, window->kernel); temp.copyTo(window->_dst(box), window->round_mask); window->round_mask.copyTo(window->zone(box), window->round_mask); imshow("Image", window->_dst); return; } imshow("Image", temp); } // user release left button if (event == CV_EVENT_LBUTTONUP && window->drag) { if (window->mode == 1) { Point temp(window->point); window->point.x = min(x, temp.x); x = max(x, temp.x); window->point.y = min(y, temp.y); y = max(y, temp.y); rectangle(window->zone, window->point, Point(x, y), Scalar(255), CV_FILLED, 8, 0); Rect box = Rect(window->point.x, window->point.y, x - window->point.x, y - window->point.y); if (window->style == 1) { medianBlur(window->_dst(box), window->_dst(box), window->kernel); medianBlur(window->_dst(box), window->_dst(box), window->kernel); } else { Mat mask = Mat::zeros(window->_src.size(), CV_8UC1); rectangle(mask, window->point, Point(x, y), CV_RGB(255, 255, 255), CV_FILLED, 8, 0); inpaint(window->_dst, mask, window->_dst, 5, INPAINT_TELEA); } } else if (window->mode == 2) { Rect box = boundingRect(window->points); vector< vector<Point> > contour; contour.push_back(window->points); Mat mask = Mat::zeros(window->_src.size(), CV_8UC1); fillPoly(mask, contour, Scalar(255)); fillPoly(window->zone, contour, Scalar(255)); if (window->style == 1) { Mat temp; medianBlur(window->_dst(box), temp, window->kernel); medianBlur(temp, temp, window->kernel); temp.copyTo(window->_dst(box), mask(box)); } else inpaint(window->_dst, mask, window->_dst, 5, INPAINT_TELEA); } imshow("Image", window->_dst); window->drag = false; } // user click right button: reset all if (event == CV_EVENT_RBUTTONUP) { window->_dst = window->_src.clone(); window->zone = Mat::zeros(window->_src.size(), CV_8UC1); window->drag = false; imshow("Image", window->_dst); } }