// Wat.. void RenderHands(CVPipeline * pipe) { List<CVHand> & hands = pipe->hands; // std::vector<std::vector<cv::Point> > c; for(int i = 0; i < hands.Size(); i++) { CVHand & hand = hands[i]; if (hand.contour && hand.contour->segments.Size()) RenderContourSegments(hand.contour, pipe); else RenderContours(pipe); // assert(hand.contour); // c.clear(); // c.push_back(hand.contour->cvPointList); cv::circle(pipe->output, cv::Point(hand.center.x, hand.center.y), 20, cv::Scalar(0, 0, 255), 2); int fingersSize = hand.fingers.Size(); for(int j = 0; j < fingersSize; j++) { #define VEC3FTOCVPOINT(a) (cv::Point(a.x,a.y)) CVFinger & finger = hand.fingers[j]; Vector3f fingerPoint = finger.point; Vector4f fingerColor = finger.GetColor(); #define VECTOCVSCALAR(a) (cv::Scalar(a.z,a.y,a.x)) cv::circle(pipe->output, cv::Point(fingerPoint.x, fingerPoint.y), 10, VECTOCVSCALAR(fingerColor), 2); cv::line(pipe->output, VEC3FTOCVPOINT(hand.center), VEC3FTOCVPOINT(fingerPoint), VECTOCVSCALAR(fingerColor), 4); Vector3f start = finger.start; if (start.MaxPart()) cv::circle(pipe->output, cv::Point(start.x, start.y), 5, cv::Scalar(255,0,125), 2); Vector3f stop = finger.stop; if (stop.MaxPart()) cv::circle(pipe->output, cv::Point(stop.x, stop.y), 5, cv::Scalar(0,255,255), 2); // Render each parallel pair in some colored circle or line? for (int i = 0; i < finger.parallelPairs.Size(); ++i) { CVContourSegmentPair & csp = finger.parallelPairs[i]; // Parallel point. Vector3f pp = csp.one.rawInputStart, pp2 = csp.two.rawInputStart; cv::circle(pipe->output, cv::Point(pp.x, pp.y), 5, cv::Scalar(155,255,155), 2); cv::circle(pipe->output, cv::Point(pp2.x, pp2.y), 5, cv::Scalar(155,255,255), 2); } } // Render approximate velocity. Vector3f vel = hand.approximateVelocityFromOpticalFlow; Vector3f colorVel = vel; colorVel.y *= -1; Vector4f color = GetColorForDirection(colorVel.NormalizedCopy()); // Paint it. cv::line(pipe->output, VectorToCVPoint(hand.center), VectorToCVPoint(hand.center + vel * 3), VectorToCVScalarColor(color), 5); // std::cout<<"\nfingers drawn: "<<hand.fingers.Size(); } }
const FTPoint& FTOutlineGlyphImpl::RenderImpl(const FTPoint& pen, int renderMode) { if(vectoriser) { RenderContours(pen); } return advance; }
void CVDataFilter::Paint(CVPipeline * pipe) { if (returnType == CVReturnType::QUADS) { // Draw quads. if (!pipe->quads.Size()) return; // Copy original input pipe->initialInput.copyTo(pipe->output); // Convert to color if needed. int channelsBefore = pipe->output.channels(); if (channelsBefore == 1) { // pipe->output.convertTo(pipe->output, CV_8UC3); cv::cvtColor(pipe->output, pipe->output, CV_GRAY2RGB); } int channelsAfter = pipe->output.channels(); // o.o Paste! for (int i = 0; i < pipe->quads.Size(); ++i) { Quad quad = pipe->quads[i]; #define RGB(r,g,b) cv::Scalar(b,g,r) rng = cv::RNG(1344); cv::Scalar color = RGB(rng.uniform(0, 255),rng.uniform(0, 255),rng.uniform(0, 255)); // cv::Mat rectImage = cv::Mat::zeros(pipe->output.size(), CV_8UC3); cv::rectangle(pipe->output, cv::Point(quad.point1.x, quad.point1.y), cv::Point(quad.point3.x, quad.point3.y), color, CV_FILLED); float alpha = 0.2f; float beta = 1 - alpha; // cv::addWeighted(rectImage, alpha, pipe->output, beta, 0.0, pipe->output); // rectImage.copyTo(pipe->output); } } else if (returnType == CVReturnType::APPROXIMATED_POLYGONS) { // Copy original input.. pipe->initialInput.copyTo(pipe->output); RenderPolygons(pipe); } else if (returnType == CVReturnType::CV_IMAGE) { // Do nothing as the image should already be in the ouput matrix of the pipeline. } else if (returnType == CVReturnType::LINES || returnType == CVReturnType::CV_LINES) { // Convert the color to colors again for visualization... pipe->initialInput.copyTo(pipe->output); for( size_t i = 0; i < pipe->lines.Size(); i++ ) { Line & line = pipe->lines[i]; // Multiply the line coordinates with the last used inverted scale. line.start *= pipe->currentScaleInv; line.stop *= pipe->currentScaleInv; cv::line( pipe->output, cv::Point(line.start.x, line.start.y), cv::Point(line.stop.x, line.stop.y), cv::Scalar(0,0,255), 3, 8 ); } } else if (returnType == CVReturnType::CV_CONTOURS) { pipe->initialInput.copyTo(pipe->output); RenderContours(pipe); } switch(returnType) { case CVReturnType::CV_CONTOUR_SEGMENTS: { // Render shit! pipe->initialInput.copyTo(pipe->output); RenderContourSegments(pipe); break; } } if (returnType == CVReturnType::CV_CONTOUR_ELLIPSES) { pipe->initialInput.copyTo(pipe->output); RenderContours(pipe); RenderContourBounds(pipe); } else if (returnType == CVReturnType::CV_CONVEX_HULLS) { pipe->initialInput.copyTo(pipe->output); RenderContours(pipe); RenderConvexHulls(pipe); } else if (returnType == CVReturnType::CV_CONVEXITY_DEFECTS) { pipe->initialInput.copyTo(pipe->output); RenderContours(pipe); RenderConvexHulls(pipe); RenderConvexityDefects(pipe); } else if (returnType == CVReturnType::HANDS) { // Convert image to RGB for easier display int channelsBefore = pipe->initialInput.channels(); // cv::cvtColor(*pipe->initialInput, pipe->output, CV_GRAY2RGB); pipe->initialInput.copyTo(pipe->output); int channelsAfter = pipe->output.channels(); // Check if we got contour-segments, if so prioritize them. RenderHands(pipe); } else if (returnType == CVReturnType::FINGER_STATES) { // Render the last known one. pipe->initialInput.copyTo(pipe->output); FingerState & state = pipe->fingerStates.Last(); cv::Scalar color(255,0,0,255); for (int i = 0; i < state.positions.Size(); ++i) { Vector3f pos = state.positions[i]; cv::circle(pipe->output, cv::Point(pos.x, pos.y), 5, color, 3); } } else if (returnType == CVReturnType::POINT_CLOUDS) { pipe->initialInput.copyTo(pipe->output); for (int i = 0; i < pipe->pointClouds.Size(); ++i) { int r,g,b,a; r = g = b = a = 255; if (i % 2 == 0) g = 0; if (i % 4 == 0) b = 0; cv::Scalar color(r,g,b,a); CVPointCloud & pc = pipe->pointClouds[i]; for (int j = 0; j < pc.points.Size(); ++j) { Vector2f & pos = pc.points[j]; cv::circle(pipe->output, cv::Point(pos.x, pos.y), 2, color, 3); } /// Render PCA data if applicable. for (int j = 0; j < pc.eigenVectors.Size(); ++j) { cv::Scalar color = j == 0? CV_RGB(255, 255, 0) : CV_RGB(0, 255, 255); cv::Point2f eigenVector(pc.eigenVectors[j].x, pc.eigenVectors[j].y); float eigenValue = pc.eigenValues[j]; cv::Point2f scaledEigenVector = eigenVector * eigenValue * 0.02; cv::Point2f pcaCenter(pc.pcaCenter.x, pc.pcaCenter.y); circle(pipe->output, pcaCenter, 3, CV_RGB(255, 0, 255), 2); line(pipe->output, pcaCenter, pcaCenter + scaledEigenVector, color); } } } else if (returnType == CVReturnType::CV_OPTICAL_FLOW) { // http://stackoverflow.com/questions/7693561/opencv-displaying-a-2-channel-image-optical-flow // Split the coordinates. /* cv::Mat xy[2]; cv::split(pipe->opticalFlow, xy); cv::Mat magnitude, angle; // Fetch matrix from pipeline. cv::cartToPolar(xy[0], xy[1], magnitude, angle, true); double magMax; cv::minMaxLoc(magnitude, 0, &magMax); magnitude.convertTo(magnitude, -1, 1.0 / magMax); // Build HSV image? cv::Mat hsvChannels[3], hsv; hsvChannels[0] = angle; hsvChannels[1] = cv::Mat::ones(angle.size(), CV_32F); hsvChannels[2] = magnitude; cv::merge(hsvChannels, 3, hsv); // Convert to rgb and send to output. cv::cvtColor(hsv, pipe->output, cv::COLOR_HSV2RGB); */ } else if (returnType == CVReturnType::NOTHING) { // Nothing to render... } else if (returnType == -1) { // Nothing to render if error. std::cout<<"\nreturnType variable in filter "<<name<<" not set!"; } else if (returnType == CVReturnType::RENDER) // Nothing to render if render. ; else ; // std::cout<<"\nCVDataFilter::Paint called. Forgot to subclass the paint-method?"; }