void RenderContourBounds(CVPipeline * pipe) { rng = cv::RNG(5553); for (int i = 0; i < pipe->contours.Size(); ++i) { CVContour * contour = &pipe->contours[i]; cv::Scalar color; switch(contour->contourClass) { case ContourClass::FINGERTIP: color = cv::Scalar(255, 0, 0); break; case ContourClass::FINGER: color = cv::Scalar(0, 255, 0); break; default: color = cv::Scalar(rng.uniform(0,225), rng.uniform(0,225), rng.uniform(0,255)); } switch(contour->boundingType) { case BoundingType::ELLIPSE: // ellipse ellipse(pipe->output, contour->boundingEllipse, color, 2, 8 ); break; case BoundingType::RECT: { // rotated rectangle cv::Point2f rect_points[4]; contour->boundingRect.points( rect_points ); for( int j = 0; j < 4; j++ ) line(pipe->output, rect_points[j], rect_points[(j+1)%4], color, 1, 8 ); break; } } } }
Plane() { n[0] = rng.uniform(-0.5, 0.5); n[1] = rng.uniform(-0.5, 0.5); n[2] = -0.3; //rng.uniform(-1.f, 0.5f); n = n / cv::norm(n); set_d(rng.uniform(-2.0, 0.6)); }
void RenderPolygons(CVPipeline * pipe) { /// Use same random seed every time to avoid rainbow hell.. rng = cv::RNG(12345); for (int i = 0; i < pipe->approximatedPolygons.size(); ++i) { cv::Scalar color = cv::Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255)); cv::drawContours(pipe->output, pipe->approximatedPolygons, i, color, 2, 8, pipe->contourHierarchy, 0, cv::Point()); } }
const cv::Vec3b Brush::get_color(const cv::Point center, const cv::Mat& reference_image, const Style& style) const { cv::Vec3b color = reference_image.at<cv::Vec3b>(center); color[0] = clamp(color[0] + color[0] * (rng.uniform(-0.5, 0.5) * style.blue_jitter())); color[1] = clamp(color[1] + color[1] * (rng.uniform(-0.5, 0.5) * style.green_jitter())); color[2] = clamp(color[2] + color[2] * (rng.uniform(-0.5, 0.5) * style.red_jitter())); cv::cvtColor(color, color, CV_RGB2HSV); color[0] = clamp(color[0] + color[0] * (rng.uniform(-0.5, 0.5) * style.hue_jitter())); color[1] = clamp(color[1] + color[1] * (rng.uniform(-0.5, 0.5) * style.saturation_jitter())); color[2] = clamp(color[2] + color[2] * (rng.uniform(-0.5, 0.5) * style.value_jitter())); cv::cvtColor(color, color, CV_HSV2RGB); return color; }
void cannyDetector(cv::Mat src, cv::Mat &imgMap) { /*Obsolete version for detection of colored contours... date : */ int ratio = 3; int kernel_size = 3; cv::Mat srcGray, srcHsv, cannyOutput; std::vector<std::vector<cv::Point> > contours; // from color to gray cv::cvtColor(src, srcGray, cv::COLOR_BGR2GRAY); // from color to hsv cv::cvtColor(src, srcHsv, cv::COLOR_BGR2HSV); /// Reduce noise with a kernel 3x3 cv::blur( srcGray, srcGray, cv::Size(3,3) ); /// Canny detector cv::Canny( srcGray, cannyOutput, lowThreshold, lowThreshold*ratio, kernel_size ); /// Find contours cv::findContours(cannyOutput, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); // Select orange contours imgMap = cv::Mat::zeros( srcGray.size(), srcGray.type() ); cv::Rect bRect = cv::Rect(0,0,0,0); for( int i = 0; i< contours.size(); i++ ) { if (cv::contourArea(contours[i]) > 0.00001*src.rows*src.cols) { bRect = cv::boundingRect(contours[i]); cv::inRange(srcHsv(bRect), cv::Scalar(h_min,50,50), cv::Scalar(h_max,255,255), imgMap(bRect)); } } cv::erode(imgMap, imgMap, getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(1, 1))); cv::dilate(imgMap, imgMap, getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3, 3))); //Draw contours cv::Mat drawing = cv::Mat::zeros( cannyOutput.size(), CV_8UC3 ); for( int i = 0; i< contours.size(); i++ ) { cv::Scalar color = cv::Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); drawContours( drawing, contours, i, cv::Scalar(0,0,255), 1, 8); } /*// Show in a window cv::namedWindow( "Contours", CV_WINDOW_AUTOSIZE ); cv::imshow( "Contours", drawing ); cv::namedWindow( "imgMap", CV_WINDOW_AUTOSIZE ); cv::imshow( "imgMap", imgMap );*/ }
void RenderConvexityDefects(CVPipeline * pipe) { cv::Scalar color = cv::Scalar(rng.uniform(155,255), rng.uniform(125,255), rng.uniform(0,200)); List<cv::Vec4i> defects = pipe->convexityDefects; for (int i = 0; i < defects.Size(); ++i) { cv::Vec4i defect = defects[i]; int farthestPointIndex = defect[2]; cv::Point farthestPoint = pipe->cvContours[0][farthestPointIndex]; // Render point furthest away? cv::circle(pipe->output, farthestPoint, 3, color, 5); } }
void CornerDetection::myShiTomasi_function(cv::Mat img, cv::Mat img_gray, cv::Mat myShiTomasi_dst) { myShiTomasi_copy = img.clone(); if( myShiTomasi_qualityLevel < 1 ) myShiTomasi_qualityLevel = 1; for( int j = 0; j < img_gray.rows; j++ ) for( int i = 0; i < img_gray.cols; i++ ) if( myShiTomasi_dst.at<float>(j,i) > myShiTomasi_minVal + ( myShiTomasi_maxVal - myShiTomasi_minVal )*myShiTomasi_qualityLevel/max_qualityLevel ) cv::circle( myShiTomasi_copy, cv::Point(i,j), 4, cv::Scalar( rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255) ), -1, 8, 0 ); cv::imshow( shiTomasi_win, myShiTomasi_copy ); }
void RenderContours(CVPipeline * pipe) { /// Use same random seed every time to avoid rainbow hell.. rng = cv::RNG(12345); for (int i = 0; i < pipe->contours.Size(); ++i) { CVContour * contour = &pipe->contours[i]; if (contour->segments.Size()) RenderContourSegments(contour, pipe); else { cv::Scalar color = cv::Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255)); cv::drawContours(pipe->output, pipe->cvContours, i, color, 2, 8, pipe->contourHierarchy, 0, cv::Point()); } } }
double randomDoubleLog(double minVal, double maxVal) { double logMin = log((double)minVal + 1); double logMax = log((double)maxVal + 1); double pow = rng.uniform(logMin, logMax); double v = exp(pow) - 1; CV_Assert(v >= minVal && (v < maxVal || (v == minVal && v == maxVal))); return v; }
void RenderConvexHulls(CVPipeline * pipe) { if (pipe->cvContours.size() == 0) return; cv::Scalar color = cv::Scalar(rng.uniform(125,255), rng.uniform(125,255), rng.uniform(125,255)); // cv::drawContours(pipe->output, pipe->convexHull, 0, color, 1, 8, std::vector<cv::Vec4i>(), 0, cv::Point() ); std::vector<int> & convexHull = pipe->convexHull; std::vector<cv::Point> & contour = pipe->cvContours[0]; for (int i = 0; i < convexHull.size(); ++i) { int index = convexHull[i]; cv::Point point = contour[index]; cv::circle(pipe->output, point, 15, color); int nextIndex = convexHull[(i+1) % convexHull.size()]; cv::Point point2 = contour[nextIndex]; // Line! cv::line(pipe->output, point, point2, color, 3); } }
Rectangle::Rectangle(const cv::Rect &_rect, const int &_id) : rect(_rect) { tl = _rect.tl(); br = _rect.br(); left = new VerticalLine(); left->set(tl, cv::Point(tl.x, br.y)); top = new HorizontalLine(); top->set(tl, cv::Point(br.x, tl.y)); bottom = new HorizontalLine(); bottom->set(cv::Point(tl.x, br.y), br); right = new VerticalLine(); right->set(cv::Point(br.x, tl.y), br); info.set(_id, _rect); selected = false; selected_color = RED_COLOR; offset = 4; lineOffset = LINE_WEIGHT; color = cv::Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); }
void drawEpipolar( cv::Mat _imga, cv::Mat _imgb, std::vector<Eigen::VectorXi> _p2Da, std::vector<Eigen::VectorXi> _p2Db, std::vector<Eigen::VectorXd> _pda, std::vector<Eigen::VectorXd> _pdb ) { char num[] = "12"; for( unsigned int i = 0; i < _p2Da.size(); i++ ) { Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255) ); sprintf( num, "%d ", i); circle( _imga, Point( _p2Da[i](0), _p2Da[i](1)), 5, color, -1, 8, 0 ); putText( _imga, num, Point( _p2Da[i](0), _p2Da[i](1) ), FONT_HERSHEY_SIMPLEX, 1, color, 2, 8, false); sprintf( num, "%d ", i); circle( _imgb, Point( _p2Db[i](0), _p2Db[i](1)), 5, color, -1, 8, 0 ); putText( _imgb, num, Point( _p2Db[i](0), _p2Db[i](1) ), FONT_HERSHEY_SIMPLEX, 1, color, 2, 8, false); Point2f pt1a; Point2f pt2a; pt1a.x = _pda[i](0); pt1a.y = _pda[i](1); pt2a.x = _pda[i](2); pt2a.y = _pda[i](3); line( _imga, pt1a, pt2a, color, 2, CV_AA ); Point2f pt1b; Point2f pt2b; pt1b.x = _pdb[i](0); pt1b.y = _pdb[i](1); pt2b.x = _pdb[i](2); pt2b.y = _pdb[i](3); line( _imgb, pt1b, pt2b, color, 2, CV_AA ); } }
void DataProviderDTang<Dtype>::shuffle() { static cv::RNG rng(time(0)); std::vector<boost::filesystem::path> shuffled_depth_paths(depth_paths_.size()); std::vector<std::vector<cv::Vec3f> > shuffled_annos(annos_.size()); for(size_t idx = 0; idx < depth_paths_.size(); ++idx) { int rand_idx = rng.uniform(0, depth_paths_.size()); shuffled_depth_paths[idx] = depth_paths_[rand_idx]; shuffled_annos[idx] = annos_[rand_idx]; } depth_paths_ = shuffled_depth_paths; annos_ = shuffled_annos; }
void CropIm(std::string destFoldPath, cv::Mat Im, double s) { int w = Im.rows; int h = Im.cols; int wStart; int hStart; wStart = rng.uniform(0.0, w*(1-s)); hStart = rng.uniform(0.0, h*(1-s)); cv::Rect myROI(hStart, wStart, h*s, w*s); cv::Mat croppedImage = Im(myROI); cv::imwrite(destFoldPath + "_crop" + int2string(int(s * 100)) + ".jpg", croppedImage); }
void gen_points_3d(std::vector<Plane>& planes_out, cv::Mat_<unsigned char> &plane_mask, cv::Mat& points3d, cv::Mat& normals, int n_planes) { std::vector<Plane> planes; for (int i = 0; i < n_planes; i++) { Plane px; for (int j = 0; j < 1; j++) { px.set_d(rng.uniform(-3.f, -0.5f)); planes.push_back(px); } } cv::Mat_ < cv::Vec3f > outp(H, W); cv::Mat_ < cv::Vec3f > outn(H, W); plane_mask.create(H, W); // n ( r - r_0) = 0 // n * r_0 = d // // r_0 = (0,0,0) // r[0] for (int v = 0; v < H; v++) { for (int u = 0; u < W; u++) { unsigned int plane_index = (u / float(W)) * planes.size(); Plane plane = planes[plane_index]; outp(v, u) = plane.intersection(u, v, Kinv); outn(v, u) = plane.n; plane_mask(v, u) = plane_index; } } planes_out = planes; points3d = outp; normals = outn; }
cv::Mat PerspectiveTransform::warpPerspectiveRand( cv::RNG& rng ) { cv::Mat H; H.create(3, 3, CV_64FC1); H.at<double>(0,0) = rng.uniform( 0.8f, 1.2f); H.at<double>(0,1) = rng.uniform(-0.1f, 0.1f); //H.at<double>(0,2) = rng.uniform(-0.1f, 0.1f)*src.cols; H.at<double>(0,2) = rng.uniform(-0.1f, 0.1f); H.at<double>(1,0) = rng.uniform(-0.1f, 0.1f); H.at<double>(1,1) = rng.uniform( 0.8f, 1.2f); //H.at<double>(1,2) = rng.uniform(-0.1f, 0.1f)*src.rows; H.at<double>(1,2) = rng.uniform(-0.1f, 0.1f); H.at<double>(2,0) = rng.uniform( -1e-4f, 1e-4f); H.at<double>(2,1) = rng.uniform( -1e-4f, 1e-4f); H.at<double>(2,2) = rng.uniform( 0.8f, 1.2f); return H; }
void Controller::generate_model(){ //Create Average images; //this->_model_depth_average = cv::Mat::zeros(cv::Size(640,480),CV_16UC1); //this->_model_color_average = cv::Mat::zeros(cv::Size(640,480),CV_8UC3); //cv::Mat average_counter = cv::Mat::zeros(cv::Size(640,480),CV_8UC1); int old_step = this->_property_manager->_3d_step; cv::Mat1i freq_n(cv::Size(640,480),0); cv::Mat1f freq_v(cv::Size(640,480),0); cv::Mat freq_c = cv::Mat::zeros(cv::Size(640,480),CV_32FC3); int idx, idx_clr; float* ptr_freq_v = (float*)freq_v.data; int* ptr_freq_n = (int*)freq_n.data; float* ptr_freq_c = (float*)freq_c.data; //Create Depth and Color Sum Image for(int k = 0 ; k < this->_model_frames_depth.size() ; ++k){ UINT16* ptr_16u = (UINT16*)this->_model_frames_depth[k].data; uint8_t* ptr_clr = (uint8_t*)this->_model_frames_color[k].data; for(int y = 0; y < XN_VGA_Y_RES ; ++y) { for(int x = 0; x < XN_VGA_X_RES ; ++x) { idx = y * XN_VGA_X_RES + x; if(ptr_16u[idx]){ ptr_freq_n[idx]++; ptr_freq_v[idx]+=ptr_16u[idx]; } idx_clr = y * XN_VGA_X_RES * 3 + x* 3; ptr_freq_c[idx_clr + 0] += ptr_clr[idx_clr + 0]; ptr_freq_c[idx_clr + 1] += ptr_clr[idx_clr + 1]; ptr_freq_c[idx_clr + 2] += ptr_clr[idx_clr + 2]; } } } //Create Depth and Color Average Image for(int y = 0; y < XN_VGA_Y_RES ; ++y) { for(int x = 0; x < XN_VGA_X_RES ; ++x) { idx = y * XN_VGA_X_RES + x; if(ptr_freq_n[idx]){ ptr_freq_v[idx] /= ptr_freq_n[idx]; } } } freq_c /= this->_model_frames_color.size(); freq_c.convertTo(this->_model_color_average,CV_8UC3); freq_v.convertTo(this->_model_depth_average,CV_16UC1); //cv::Mat t8u; //this->_model_depth_average.convertTo(t8u,CV_8UC1,0.05); //cv::imshow("win1",this->_model_color_average); ////cv::imshow("win2",this->_mat_color_bgr); //cv::imshow("win3",t8u); //cv::imshow("win4",this->_mat_depth8UC1); //cv::waitKey(); //Create Masks for avg images cv::Mat main_mask; cv::inRange(this->_model_depth_average, this->_property_manager->_depth_min, this->_property_manager->_depth_max, main_mask); cv::bitwise_and(main_mask,this->_mask_mirrors_and_foor,main_mask); //Contours to remove noise cv::Mat t8u; main_mask.convertTo(t8u,CV_8UC1,0.05); //cv::Mat image_temp; //this->_model_depth_average.copyTo(image_temp); cv::vector<cv::vector<cv::Point> > contours; cv::vector<cv::Vec4i> hierarchy; cv::findContours( t8u, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) ); for(unsigned int i = 0; i< contours.size(); i++ ){ if(contours[i].size() < 50){ cv::Scalar clr = cv::Scalar(/*255);// */rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); cv::Rect rect = cv::boundingRect(contours[i]); drawContours( this->_model_color_average, contours, i, clr, -1, 8, hierarchy, 0, cv::Point() ); //cv::rectangle(top_view_color,rect, clr); } } Mirror* mirror; uchar* ptr_mirror_mask = this->_mask_mirrors.data; //Generate 3D this->_model_n_points; uchar* ptr_main_mask = main_mask.data; //uchar* ptr_mirror_mask = this->_mask_mirrors.data; UINT16* ptr_16u = (UINT16*)this->_model_depth_average.data; for(int y = 0; y < XN_VGA_Y_RES ; ++y /*y += this->_property_manager->_3d_step*/) { for(int x = 0; x < XN_VGA_X_RES ; ++x/*x += this->_property_manager->_3d_step*/) { idx = y * XN_VGA_X_RES + x; if(ptr_main_mask[idx]){ XnPoint3D point1; point1.X = x; point1.Y = y; point1.Z = ptr_16u[idx]; if(ptr_mirror_mask[idx]){ for(int j = 0 ; j < this->_mirrors.size() ; ++j){ mirror = this->_mirrors[j]; if(mirror && mirror->_area_mask.data[idx]){ if(point1.Z > mirror->_depth_min && point1.Z < mirror->_depth_max){ this->_model_back_3d_to_2d[this->_model_n_points][XX] = x; this->_model_back_3d_to_2d[this->_model_n_points][YY] = y; this->_model_projective[this->_model_n_points++] = point1; } } } } else{ this->_model_back_3d_to_2d[this->_model_n_points][XX] = x; this->_model_back_3d_to_2d[this->_model_n_points][YY] = y; this->_model_projective[this->_model_n_points++] = point1; } } } } bool result = this->_kinect->convert_to_realworld( this->_model_n_points, this->_model_projective, this->_model_realworld); //uint8_t* ptr_clr = (uint8_t*)this->_model_color_average.data; //Generate PCL-3D Floor //uchar* ptr_mask_floor = mask_floor.data; //for(int y = 0; y < XN_VGA_Y_RES ; y += this->_property_manager->_3d_step) { // for(int x = 0; x < XN_VGA_X_RES ; x += this->_property_manager->_3d_step) { // //if(ptr_mask_floor[y * XN_VGA_X_RES + x]){ // //} // } //} //Generate PCL-3D from Mirrors _pcl_cloud.clear(); uchar* ptr = this->_mask_main.data; uint8_t* ptr_clr = (uint8_t*)this->_model_color_average.data; _model_cloud.clear(); int xx, yy; double dist; std::vector<double> nx,ny,nz; for(int i = 0 ; i < this->_mirrors.size() ; ++i){ double nx_,ny_,nz_; mirror = this->_mirrors[i]; if(mirror){ mirror->_n_points = 0; mirror->_plane.get_normal(&nx_,&ny_,&nz_); nx_ *= -1; ny_ *= -1; nz_ *= -1; nx.push_back(nx_); ny.push_back(ny_); nz.push_back(nz_); } } for(int i = 0 ; i < this->_model_n_points ; ++i){ xx = this->_model_back_3d_to_2d[i][XX]; yy = this->_model_back_3d_to_2d[i][YY]; idx = yy * XN_VGA_X_RES + xx; if(ptr_mirror_mask[idx]){ for(int j = 0 ; j < this->_mirrors.size() ; ++j){ mirror = this->_mirrors[j]; if(mirror && mirror->_area_mask.data[idx]){ //if(this->_model_realworld[i].Z > mirror->_depth_min && this->_model_realworld[i].Z < mirror->_depth_max){ dist = mirror->_plane.distance_to_plane( this->_model_realworld[i].X, this->_model_realworld[i].Y, this->_model_realworld[i].Z); this->_model_realworld[i].X += 2 * dist * nx[j]; this->_model_realworld[i].Y += 2 * dist * ny[j]; this->_model_realworld[i].Z += 2 * dist * nz[j]; //} } } } dist = this->_floor->_plane.distance_to_plane( this->_model_realworld[i].X, this->_model_realworld[i].Y, this->_model_realworld[i].Z); if(dist > this->_floor->_thresh){ pcl::PointXYZRGB pt(ptr_clr[yy * XN_VGA_X_RES * 3 + xx* 3 + 2], ptr_clr[yy * XN_VGA_X_RES * 3 + xx* 3 + 1], ptr_clr[yy * XN_VGA_X_RES * 3 + xx* 3 + 0]); pt.x = this->_model_realworld[i].X; pt.y = this->_model_realworld[i].Y; pt.z = this->_model_realworld[i].Z; this->_model_cloud.push_back(pt); } } this->_property_manager->_3d_step = old_step; this->_property_manager->_flag_processed[PropertyManager::P_CAPTURE_SHOW] = true; }
static cv::Scalar randomScalar() { static cv::RNG rng(12345); return cv::Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); }
int main( int argc, char** argv ) { /// Load an image cv::Mat src, greyIm, histeqIm; src = cv::imread( argv[1] ); if( !src.data ) { printf("Input file? No? ouuuupsss thooooorryyyyy\n"); return -1; } cv::Size s = src.size(); int rows = s.height; int cols = s.width; // Setup a rectangle to define your region of interest cv::Rect myROI(0, rows/2, cols, rows/2); // Crop the full image to that image contained by the rectangle myROI // Note that this doesn't copy the data cv::Mat croppedImage = src(myROI); cv::imwrite("output/1_low_half.jpg", croppedImage); cv::cvtColor(croppedImage, greyIm, cv::COLOR_BGR2GRAY); cv::Size crop_size = croppedImage.size(); int crop_rows = crop_size.height; int crop_cols = crop_size.width; cv::imwrite("output/2_grey_scale.jpg", greyIm); cv::equalizeHist( greyIm, histeqIm ); cv::imwrite("output/3_hist_eq.jpg", histeqIm); std::vector<std::vector<cv::Point> > contours; std::vector<cv::Vec4i> hierarchy; // Reduce noise with kernel 3x3 cv::Mat blurIm; blur(histeqIm, blurIm, cv::Size(3,3)); cv::imwrite("output/4_blur.jpg", blurIm); // Canny detector cv::Mat edgesIm; Canny(blurIm, edgesIm, thresh, thresh*ratio, kernel_size); cv::imwrite("output/5_edge.jpg", edgesIm); // Find contours cv::findContours(edgesIm, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE, cv::Point(0,0)); // Approximate contours to polygons + get bounding rects and circles std::vector<std::vector<cv::Point> > contours_poly(contours.size()); std::vector<cv::Rect> boundRect(contours.size()); std::vector<cv::Point2f>center(contours.size()); std::vector<float>radius(contours.size()); for (int i = 0; i < contours.size(); i++) { cv::approxPolyDP(cv::Mat(contours[i]), contours_poly[i], 3, true); boundRect[i] = cv::boundingRect(cv::Mat(contours_poly[i])); cv::minEnclosingCircle((cv::Mat)contours_poly[i], center[i], radius[i]); } // Draw contours int j=0; cv::Mat drawing = cv::Mat::zeros(edgesIm.size(), CV_8UC3); cv::Mat piece[5], hsvIm[5]; for (int i = 0; i < contours.size(); i++) { if (!((boundRect[i].height >= boundRect[i].width/5) && (boundRect[i].height <= boundRect[i].width/2) && boundRect[i].height<=crop_rows/4 && boundRect[i].width<=crop_cols/2 && boundRect[i].height>=crop_rows/10 && boundRect[i].width>=crop_cols/6)) continue; cv::Rect roi = boundRect[i]; piece[j] = croppedImage(roi); imwrite("output/contour"+std::to_string(j)+".jpg", piece[j]); j++; cv::Scalar color = cv::Scalar(rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255)); cv::drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, cv::Point()); cv::rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0); //circle(drawing, center[i], (int)radius[i], color, 2, 8, 0); } imwrite("output/6_contours.jpg", drawing); int h_bins = 50; int s_bins = 60; int histSize[] = { h_bins, s_bins }; float h_ranges[] = { 0, 180 }; float s_ranges[] = { 0, 256 }; const float* ranges[] = { h_ranges, s_ranges }; int channels[] = { 0, 1 }; cv::Mat hist[5]; for (int i=0; i<j; i++){ cvtColor(piece[i], hsvIm[i], cv::COLOR_BGR2HSV); imwrite("output/hsvIm"+std::to_string(i)+".jpg", hsvIm[i]); calcHist( &hsvIm[i], 1, channels, cv::Mat(), hist[i], 2, histSize, ranges, true, false ); //normalize( hsvIm[i], hsvIm[i], 0, 1, cv::NORM_MINMAX, -1, cv::Mat() ); } return 0; }
void thresh_callback(int, void* ) { cv::Mat canny_output; std::vector<std::vector<cv::Point> > contours; std::vector<cv::Vec4i> hierarchy; /// Detect edges using canny cv::threshold( blur, canny_output, thresh, 255 ,1 ); cv::namedWindow("canny",CV_WINDOW_NORMAL); cv::imshow("canny",canny_output); /// Find contours cv::findContours( canny_output, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE, cv::Point(0, 0) ); for( int f =0; f <listOfMarks.size();f++) { delete listOfMarks[f]; } listOfMarks.clear(); /// Draw contours cv::Mat drawing = cv::Mat::zeros( canny_output.size(), CV_8UC3 ); for( size_t i = 0; i< contours.size(); i++ ) { cv::Scalar color = cv::Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); cv::drawContours( drawing, contours, (int)i, cv::Scalar(255,255,255), thick, 8, hierarchy, 0, cv::Point() ); // mark *temp = new mark(contours[i]); // listOfMarks.push_back(temp); } /// Show in a window cv::namedWindow( "Contours", CV_WINDOW_NORMAL ); cv::imshow( "Contours", drawing ); //-------------------------------------------again std::vector<std::vector<cv::Point> > contours_again; std::vector<cv::Vec4i> hierarchy_again; draw_again = cv::Mat::zeros( canny_output.size(), CV_8UC3 ); colorOutImage = cv::Mat::zeros(canny_output.size(), CV_8UC3); cv::Mat temp; cv::cvtColor( drawing,temp, cv::COLOR_BGR2GRAY ); cv::findContours( temp , contours_again, hierarchy_again, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE, cv::Point(0, 0) ); for( size_t i = 0; i< contours_again.size(); i++ ) { // cv::Scalar color = cv::Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); cv::Scalar color = cv::Scalar(255,255,255); cv::drawContours( draw_again, contours_again, (int)i, color , 2, 8, hierarchy, 0, cv::Point() ); mark * temp = new mark(contours_again[i]); listOfMarks.push_back(temp); } /// Show in a window // cv::namedWindow( "Contours_again", CV_WINDOW_NORMAL ); // cv::imshow( "Contours_again", draw_again ); for(int h = 0; h < listOfMarks.size();h++) { int y = (listOfMarks[h]->high_y() + listOfMarks[h]->low_y()) / 2; int x1 = listOfMarks[h]->high_x() + length; int x2 = listOfMarks[h]->low_x() - length; cv::Point one = cv::Point(x1,y); cv::Point two = cv::Point(x2,y); cv::Scalar white =cv::Scalar(255,255,255); cv::line(draw_again, one, two, white, thick,8,0); } cv::namedWindow( "Contours_again", CV_WINDOW_NORMAL ); cv::imshow( "Contours_again", draw_again ); std::vector< std::vector<cv::Point> > contour_3; std::vector<cv::Vec4i> hierarchy_3; cv::Mat temp_3; cv::cvtColor( draw_again,temp_3, cv::COLOR_BGR2GRAY ); std::cerr<<"cvtColo" <<std::endl; cv::findContours( temp_3, contour_3, hierarchy_3, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE, cv::Point(0, 0) ); std::cerr<<"found contours" << std::endl; for( size_t i = 0; i< contour_3.size(); i++ ) { cv::Scalar color = cv::Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); // cv::Scalar color = cv::Scalar(255,255,255); cv::drawContours( colorOutImage, contour_3, (int)i, color , 2, 8, hierarchy_3, 0, cv::Point() ); } std::cerr<<"drawContours"<<std::endl; cv::namedWindow( "Contours_3", CV_WINDOW_NORMAL ); cv::imshow( "Contours_3", colorOutImage ); std::cout<<std::endl<<"number of contours -> " <<contours.size(); //again-------------------------------------------------------------------------- // makeZones_callback(0,0); }
JNIEXPORT void JNICALL Java_ph_edu_dlsu_circles_CameraActivity_process(JNIEnv *env, jobject instance, jobject pTarget, jbyteArray pSource, jint thresh) { uint32_t t; cv::Mat srcBGR; cv::Mat edges; cv::Scalar color; std::vector<cv::Vec3f> circles; AndroidBitmapInfo bitmapInfo; uint32_t* bitmapContent; if(AndroidBitmap_getInfo(env, pTarget, &bitmapInfo) < 0) abort(); if(bitmapInfo.format != ANDROID_BITMAP_FORMAT_RGBA_8888) abort(); if(AndroidBitmap_lockPixels(env, pTarget, (void**)&bitmapContent) < 0) abort(); /// Access source array data... OK jbyte* source = (jbyte*)env->GetPrimitiveArrayCritical(pSource, 0); if (source == NULL) abort(); /// cv::Mat for YUV420sp source and output BGRA cv::Mat srcGray(bitmapInfo.height, bitmapInfo.width, CV_8UC1, (unsigned char *)source); cv::Mat src(bitmapInfo.height + bitmapInfo.height/2, bitmapInfo.width, CV_8UC1, (unsigned char *)source); cv::Mat mbgra(bitmapInfo.height, bitmapInfo.width, CV_8UC4, (unsigned char *)bitmapContent); /***********************************************************************************************/ /// Native Image Processing HERE... t = cv::getTickCount(); if(srcBGR.empty()) srcBGR = cv::Mat(bitmapInfo.height, bitmapInfo.width, CV_8UC3); cv::cvtColor(src, srcBGR, CV_YUV420sp2RGB); // Reduce noise cv::GaussianBlur( srcGray, srcGray, cv::Size(9, 9), 2, 2 ); // Detect the circles cv::HoughCircles(srcGray, circles, CV_HOUGH_GRADIENT, 1, srcGray.rows/4, 200, thresh > 0 ? thresh : 1, 5); // Draw the circles for(size_t i = 0; i < circles.size(); i++) { cv::Point center(cvRound(circles[i][0]), cvRound(circles[i][1])); int radius = cvRound(circles[i][2]); color = cv::Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); // draw the circle center cv::circle(srcBGR, center, 3, color, -1, 8, 0); // draw the circle outline cv::circle(srcBGR, center, radius, color, 3, 8, 0); } LOGI("Processing took %0.2f ms.", 1000*((float)cv::getTickCount() - t)/(float)cv::getTickFrequency()); cvtColor(srcBGR, mbgra, CV_BGR2BGRA); /************************************************************************************************/ /// Release Java byte buffer and unlock backing bitmap //env-> ReleasePrimitiveArrayCritical(pSource,source,0); /* * If 0, then JNI should copy the modified array back into the initial Java * array and tell JNI to release its temporary memory buffer. * * */ env-> ReleasePrimitiveArrayCritical(pSource, source, JNI_COMMIT); /* * If JNI_COMMIT, then JNI should copy the modified array back into the * initial array but without releasing the memory. That way, the client code * can transmit the result back to Java while still pursuing its work on the * memory buffer * * */ /* * Get<Primitive>ArrayCritical() and Release<Primitive>ArrayCritical() * are similar to Get<Primitive>ArrayElements() and Release<Primitive>ArrayElements() * but are only available to provide a direct access to the target array * (instead of a copy). In exchange, the caller must not perform blocking * or JNI calls and should not hold the array for a long time * */ if (AndroidBitmap_unlockPixels(env, pTarget) < 0) abort(); }
void getDistortionValues(cv::RNG &rng, const Size2i &inputSize, AugParams *agp) { // This function just gets the random distortion values without modifying the // image itself. Useful if we need to reapply the same transformations over // again (e.g. for all frames of a video or for a corresponding target mask) // colornoise values // N.B. if _contrastMax == 100, then _colorNoiseStd will be 0.0 for (int i=0; i<3; i++) { agp->colornoise[i] = rng.gaussian(_colorNoiseStd); } // contrast, brightness, saturation // N.B. all value ranges tied to _contrastMin and _contrastMax for (int i=0; i<3; i++) { agp->cbs[i] = rng.uniform(_contrastMin, _contrastMax) / 100.0f; } /************************** * HORIZONTAL FLIP * ***************************/ agp->flip = _flip && rng(2) != 0 ? true : false; /************************** * ROTATION ANGLE * ***************************/ agp->angle = rng.uniform(_rotateMin, _rotateMax); /************************** * CROP BOX * ***************************/ float shortSide = std::min(inputSize.height, inputSize.width); // Special case where we just grab the whole image; if (_scaleMin == 0) { agp->cropBox = Rect(Point2i(), inputSize); return; } if (_center) { agp->cropBox.width = shortSide * _width / (float) _scaleMin; agp->cropBox.height = shortSide * _height / (float) _scaleMin; agp->cropBox.x = (inputSize.width - agp->cropBox.width) / 2; agp->cropBox.y = (inputSize.height - agp->cropBox.height) / 2; } else { cv::Size2f oSize = inputSize; // This is a hack for backward compatibility. // Valid aspect ratio range ( > 100) will override side scaling behavior if (_aspectRatio == 0) { float scaleFactor = rng.uniform(_scaleMin, _scaleMax); agp->cropBox.width = shortSide * _width / scaleFactor; agp->cropBox.height = shortSide * _height / scaleFactor; } else { float mAR = (float) _aspectRatio / 100.0f; float nAR = rng.uniform(1.0f / mAR, mAR); float oAR = oSize.width / oSize.height; // between minscale pct% to 100% subject to aspect ratio limitation float maxScale = nAR > oAR ? oAR / nAR : nAR / oAR; float minScale = std::min((float) _scaleMin / 100.0f, maxScale); float tgtArea = rng.uniform(minScale, maxScale) * oSize.area(); agp->cropBox.height = sqrt(tgtArea / nAR); agp->cropBox.width = agp->cropBox.height * nAR; } agp->cropBox.x = rng.uniform(0, inputSize.width - agp->cropBox.width); agp->cropBox.y = rng.uniform(0, inputSize.height - agp->cropBox.height); } return; }
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?"; }
int main_center_of_mass(int argc, char* argv[]){ char* file = "contours.png"; int thresh = 100; //src.convertTo(src_gray,CV_8U); while(true){ cv::Mat src = cv::imread(file); cv::Mat src_gray;// = cv::imread(file,0); cv::cvtColor(src,src_gray,CV_RGB2GRAY); cv::dilate( src_gray, src_gray, cv::Mat() ); cv::erode( src_gray, src_gray, cv::Mat() ); //cv::threshold(src,src_gray,0.5,255,CV_THRESH_BINARY); cv::Mat1b src_g; cv::cvtColor(src,src_g,CV_RGB2GRAY); cv::Mat canny_output; cv::vector<cv::vector<cv::Point> > contours; cv::vector<cv::Vec4i> hierarchy; /// Detect edges using canny cv::Canny( src_gray, canny_output, thresh, thresh*2, 3 ); cv::imshow("canny",canny_output); /// Find contours cv::findContours( canny_output, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) ); cv::Mat drawing = cv::Mat::zeros( canny_output.size(), CV_8UC3 ); int idx = 0; int max = -1; for(unsigned int i = 0; i< contours.size(); i++ ){ cv::Scalar color3 = cv::Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); drawContours( drawing, contours, i, color3, 2, 8, hierarchy, 0, cv::Point() ); int coiso = contours.at(i).size(); if(coiso > max){ idx = i; max = coiso; } } cv::Moments mm = moments( contours[idx], false ); cv::Point2f center = cv::Point2f((float)(mm.m10/mm.m00) , (float)(mm.m01/mm.m00)); cv::Rect rect = cv::boundingRect(cv::Mat(contours[idx])); for(unsigned int i = rect.y ; i < rect.y + rect.height; i++){ for(unsigned int j = rect.x ; j < rect.x + rect.width ; j++){ cv::Scalar color2 = cv::Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); if(src_gray.ptr<unsigned char>(i)[j]){ drawing.ptr<unsigned char>(i)[3*j] = (unsigned char)color2.val[0]; // first channel drawing.ptr<unsigned char>(i)[3*j+1]= (unsigned char)color2.val[1]; // second channel drawing.ptr<unsigned char>(i)[3*j+2]= (unsigned char)color2.val[2]; // third channel //cv::circle( drawing, pt, 1, color2, -1, 2, 0 ); } } } cv::Scalar color = cv::Scalar( 255, 255, 255 ); drawContours( drawing, contours, idx, color, 2, 8, hierarchy, 0, cv::Point() ); cv::circle( drawing, center, 4, color, -1, 8, 0 ); cv::rectangle(src,rect,color); /* /// Get the moments cv::vector<cv::Moments> mu(contours.size() ); for( int i = 0; i < contours.size(); i++ ) { mu[i] = moments( contours[i], false ); } /// Get the mass centers: cv::vector<cv::Point2f> mc( contours.size() ); for( int i = 0; i < contours.size(); i++ ) { mc[i] = cv::Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 ); } cv::Mat drawing = cv::Mat::zeros( canny_output.size(), CV_8UC3 ); cv::Scalar color = cv::Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); drawContours( drawing, contours, idx, color, 2, 8, hierarchy, 0, cv::Point() ); cv::circle( src, mc[idx], 4, color, -1, 8, 0 );*/ cv::imshow("src2",src); cv::imshow("cont",drawing); cv::waitKey(22); } return 0; }
testing::Values(1.0f, 10.0f))) { const cv::Size size = std::tr1::get<0>(GetParam()); const float dp = std::tr1::get<1>(GetParam()); const float minDist = std::tr1::get<2>(GetParam()); const int minRadius = 10; const int maxRadius = 30; const int cannyThreshold = 100; const int votesThreshold = 15; cv::RNG rng(123456789); cv::Mat src(size, CV_8UC1, cv::Scalar::all(0)); const int numCircles = rng.uniform(50, 100); for (int i = 0; i < numCircles; ++i) { cv::Point center(rng.uniform(0, src.cols), rng.uniform(0, src.rows)); const int radius = rng.uniform(minRadius, maxRadius + 1); cv::circle(src, center, radius, cv::Scalar::all(255), -1); } cv::ocl::oclMat ocl_src(src); cv::ocl::oclMat ocl_circles; declare.time(10.0).iterations(25); TEST_CYCLE() {
int randomInt(int minVal, int maxVal) { return rng.uniform(minVal, maxVal); }
double randomDouble(double minVal, double maxVal) { return rng.uniform(minVal, maxVal); }
void extractPatch(cv::Mat &img, int *hull, int bbW, int bbH, unsigned char filledColor, cv::RNG &rng, double noise, double angle, double shift, double scale, cv::Mat & noiseM, cv::Mat &result) { int cpX = (hull[0] + hull[2]) / 2; int cpY = (hull[1] + hull[3]) / 2; cv::Mat h = cv::Mat::eye(3, 3, CV_64FC1); cv::Mat temp = cv::Mat::eye(3, 3, CV_64FC1); double *tempPtr = temp.ptr<double>(); double sc; double ang, ca, sa; double shR, shC; double xMin, yMin, xMax, yMax; unsigned char *resPtr; double *noisePtr; int size; //****Translating... shR = shift * bbH * (rng.uniform(1e-4, 1.)-0.5); shC = shift * bbW * (rng.uniform(1e-4, 1.)-0.5); *(tempPtr + 2) = shC; *(tempPtr + temp.cols + 2) = shR; h *= temp; //Reset... *(tempPtr + 2) = 0.0; *(tempPtr + temp.cols + 2) = 0.0; //****Rotating... ang = 2 * CV_PI / 360.0 * angle * (rng.uniform(1e-4, 1.)-0.5); ca = cos(ang); sa = sin(ang); *tempPtr = ca; *(tempPtr + 1) = -sa; *(tempPtr + temp.cols) = sa; *(tempPtr + temp.cols + 1) = ca; h *= temp; //Reset... *tempPtr = 1.0; *(tempPtr + 1) = 0.0; *(tempPtr + temp.cols) = 0.0; *(tempPtr + temp.cols + 1) = 1.0; //****Scaling... sc = 1.0 - scale*(rng.uniform(1e-4, 1.)-0.5); *tempPtr = (double)sc; *(tempPtr + temp.cols + 1) = (double)sc; h *= temp; //Reset... *tempPtr = 1.0; *(tempPtr + temp.cols + 1) = 1.0; //****Shifting Center of BB to (0, 0)... *(tempPtr + 2) = -cpX; *(tempPtr + temp.cols + 2) = -cpY; h *= temp; //Now Warp the Patch... bbW--; bbH--; xMin = -bbW / 2.0; yMin = -bbH / 2.0; xMax = bbW / 2.0; yMax = bbH / 2.0; warpImageROI(img, xMin, yMin, xMax, yMax, bbW, bbH, h, filledColor, result.data); //Add Random Noise... rng.fill(noiseM, cv::RNG::NORMAL, cv::Mat::zeros(1,1,CV_64FC1), cv::Mat::ones(1,1,CV_64FC1)); noiseM *= noise; //Here OpenCV Applies Saturation Arithmetic by Itself... cv::add(result, noise, result, cv::noArray(), CV_8UC1); }
/** * Detect people using background segmentation and contours * BSN2013 */ static vector<cv::Mat> detectPeopleSegment(cv::Mat image) { vector<cv::Mat> points; // convert to HSV cv::Mat imageHSV; cv::cvtColor(image, imageHSV, CV_BGR2HSV); vector<cv::Mat> imageHSVSlices; cv::split(imageHSV, imageHSVSlices); //cv::threshold(imageHSVSlices[0], imageHSVSlices[0], 160, 200, cv::THRESH_BINARY); // background subtraction cv::Mat fgMask; bgmodel(image, fgMask, learningRate); // tidy foreground mask cv::GaussianBlur(fgMask, fgMask, cv::Size(1, 1), 0, 0); int erosionSize = 5; cv::Mat element = cv::getStructuringElement( cv::MORPH_ELLIPSE, cv::Size(2*erosionSize+1, 2*erosionSize+1), cv::Point( erosionSize, erosionSize )); cv::dilate(fgMask, fgMask, element); cv::erode(fgMask, fgMask, element); cv::erode(fgMask, fgMask, element); cv::dilate(fgMask, fgMask, element); cv::Mat background; bgmodel.getBackgroundImage(background); //cv::imshow("back", background); // subtract background from original image cv::Mat foreground; //cv::not cv::threshold(fgMask, fgMask, 128, 255, cv::THRESH_BINARY); image.copyTo(foreground, fgMask); cv::imshow("fg", fgMask); cv::imshow("fore", foreground); // edge information int lowThreshold = 100; int ratio = 3; int kernelSize = 3; cv::Mat imageCanny; cv::Canny(foreground, imageCanny, lowThreshold, lowThreshold*ratio, kernelSize); // weight map and weighted-gradient image // apply Gaussian filter (size = 9 and sigma = 1.5) to edge information from foreground image // create Gaussian filter // weight map cv::Mat weightMap; cv::GaussianBlur(imageCanny, weightMap, cv::Size(9, 9), 1.5, 1.5); // gradient image cv::Mat imageGray; cv::cvtColor(image, imageGray, CV_BGR2GRAY); cv::Mat imageGradient; cv::Mat imageGradientX; cv::Mat imageGradientY; cv::Mat imageAbsGradientX; cv::Mat imageAbsGradientY; cv::Sobel(imageGray, imageGradientX, CV_16S, 1, 0, 3, 1, 0, cv::BORDER_DEFAULT); cv::Sobel(imageGray, imageGradientY, CV_16S, 0, 1, 3, 1, 0, cv::BORDER_DEFAULT); cv::convertScaleAbs(imageGradientX, imageAbsGradientX); cv::convertScaleAbs(imageGradientY, imageAbsGradientY); cv::addWeighted(imageAbsGradientX, 0.5, imageAbsGradientY, 0.5, 0, imageGradient); // weighted-gradient image cv::Mat weightedGradient; cv::Mat colourWeightMap; weightedGradient = imageGradient.mul(weightMap); // object (body) contours vector< vector<cv::Point> > objectContours; vector<cv::Vec4i> objectHierarchy; cv::findContours(fgMask, objectContours, objectHierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0)); // bodies and heads // store index of detected body contours and position of head vector<int> bodies; vector<cv::Point2f> headCenter; vector<float> headRadius; // detect big bodies for (int i = 0; i < objectContours.size(); i++) { // if contour is too big if (getContourRadius(objectContours[i]) > BODYSIZE*2) { // increment merged counter numMerged++; cout << "Merged object" << endl; // TODO cut down to size // TODO consider just slicing it // process contour by eroding it cv::Mat largeContour = cv::Mat::zeros(imageCanny.size(), CV_8UC3); drawContours(largeContour, objectContours, i, colourRed, CV_FILLED, 8, objectHierarchy, 0, cv::Point()); // erode until large contour becomes 2+ vector< vector<cv::Point> > largeContours; vector<cv::Vec4i> largeHierarchy; do { cv::erode(largeContour, largeContour, element); cv::Canny(largeContour, largeContour, lowThreshold, lowThreshold*ratio, kernelSize); cv::findContours(largeContour, largeContours, largeHierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0)); } while (largeContours.size() == 1); // || (largeContours.size() == 1 && getContourRadius(largeContours[0]) >= BODYSIZE)); // TODO potential infinite bug here if (largeContours.size() > 1) { // increment split counter numSplit++; cout << "Split object" << endl; } else if (largeContours.size() == 1) { // increment unsplit counter numUnsplit++; cout << "No split - size still 1" << endl; } for (int j = 0; j < largeContours.size(); j++) { objectContours.push_back(largeContours[j]); } } } cv::Mat bodiesHeads = cv::Mat::zeros(image.size(), CV_8UC3); // detect bodies for (int i = 0; i < objectContours.size(); i++) { if (isBody(objectContours[i])) { // predict head position cv::Point2f defaultHeadCenter; // body bounding box cv::RotatedRect minBodyRect; minBodyRect = cv::minAreaRect(cv::Mat(objectContours[i])); // body bounding circle radius float headOffset = getContourRadius(objectContours[i]); //*0.7; // image centre cv::Point2f imageCentre(image.size().width/2, image.size().height/2); // find gradient float m = (minBodyRect.center.y - imageCentre.y)/(minBodyRect.center.x - imageCentre.x); // find angle double angle; if (minBodyRect.center.x <= imageCentre.x && minBodyRect.center.y < imageCentre.y) { // top left quad angle = atan((imageCentre.x - minBodyRect.center.x)/(imageCentre.y - minBodyRect.center.y)); } else if (minBodyRect.center.x <= imageCentre.x) { // bottom left quad angle = PI - atan((imageCentre.x - minBodyRect.center.x)/(minBodyRect.center.y - imageCentre.y)); } else if (minBodyRect.center.x > imageCentre.x && minBodyRect.center.y > imageCentre.y) { // bottom right quad angle = PI + atan((minBodyRect.center.x - imageCentre.x)/(minBodyRect.center.y - imageCentre.y)); } else { // top right quad angle = 2*PI - atan((minBodyRect.center.x - imageCentre.x)/(imageCentre.y - minBodyRect.center.y)); } do { headOffset *= 0.7; defaultHeadCenter = cv::Point2f(minBodyRect.center.x - headOffset * sin(angle), minBodyRect.center.y - headOffset * cos(angle)); } while (cv::pointPolygonTest(objectContours[i], defaultHeadCenter, true) <= 0 && headOffset >= 1); // store body and head if body big enough for head if (headOffset >= 1) { // store body bodies.push_back(i); //angle = angle * 180/PI; headCenter.push_back(defaultHeadCenter); headRadius.push_back(0); // default head size // get detailed contours of body cv::Mat bodyMask = cv::Mat::zeros(image.size(), CV_8UC1); drawContours(bodyMask, objectContours, i, colourWhite, CV_FILLED, 8, objectHierarchy, 0, cv::Point()); //cv::floodFill(bodyMask, cv::Point2i(0, 0), cv::Scalar(1)); cv::Mat body; image.copyTo(body, bodyMask); //cv::imshow("B", body); // body edges cv::Mat bodyCanny; cv::Canny(body, bodyCanny, lowThreshold, lowThreshold*ratio, kernelSize); // weight map cv::Mat bodyWeightMap; cv::GaussianBlur(bodyCanny, bodyWeightMap, cv::Size(9, 9), 1.5, 1.5); // gradient image cv::Mat bodyGray; cv::cvtColor(body, bodyGray, CV_BGR2GRAY); cv::Mat bodyGradient; cv::Mat bodyGradientX; cv::Mat bodyGradientY; cv::Mat bodyAbsGradientX; cv::Mat bodyAbsGradientY; cv::Sobel(bodyGray, bodyGradientX, CV_16S, 1, 0, 3, 1, 0, cv::BORDER_DEFAULT); cv::Sobel(bodyGray, bodyGradientY, CV_16S, 0, 1, 3, 1, 0, cv::BORDER_DEFAULT); cv::convertScaleAbs(bodyGradientX, bodyAbsGradientX); cv::convertScaleAbs(bodyGradientY, bodyAbsGradientY); cv::addWeighted(bodyAbsGradientX, 0.5, bodyAbsGradientY, 0.5, 0, bodyGradient); // weighted-gradient image cv::Mat bodyWeightedGradient; bodyWeightedGradient = bodyGradient.mul(bodyWeightMap); // body contours vector< vector<cv::Point> > bodyContours; vector<cv::Vec4i> bodyHierarchy; cv::findContours(bodyWeightedGradient, bodyContours, bodyHierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0)); // detect head for (int j = 0; j < bodyContours.size(); j++) { // process contour by eroding it cv::Mat aContour = cv::Mat::zeros(image.size(), CV_8UC3); drawContours(aContour, bodyContours, j, colourWhite, CV_FILLED, 8, bodyHierarchy, 0, cv::Point()); drawContours(bodiesHeads, bodyContours, j, colourWhite, 2, 8, bodyHierarchy, 0, cv::Point()); cv::erode(aContour, aContour, element); //cv::erode(aContour, aContour, element); //cv::dilate(aContour, aContour, element); cv::Canny(aContour, aContour, lowThreshold, lowThreshold*ratio, kernelSize); vector< vector<cv::Point> > subContours; vector<cv::Vec4i> subHierarchy; cv::findContours(aContour, subContours, subHierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0)); // for (int k = 0; k < subContours.size(); k++) { //cv::drawContours(imageContours, subContours, k, cv::Scalar(0, 255, 0), 2, 8, subHierarchy, 0, cv::Point()); if (isHead(subContours[k], objectContours[i])) { vector<cv::Point> contourPoly; cv::Point2f center; float radius; if (subContours.size() > 1) { approxPolyDP(cv::Mat(subContours[k]), contourPoly, 3, true); } else { approxPolyDP(cv::Mat(bodyContours[j]), contourPoly, 3, true); } minEnclosingCircle((cv::Mat)contourPoly, center, radius); float distanceOld = euclideanDistance(headCenter[headCenter.size() - 1], defaultHeadCenter); float distanceNew = euclideanDistance(center, defaultHeadCenter); if (headRadius[headRadius.size() - 1] == 0 || (distanceOld > 0 && distanceNew < distanceOld)) { // store first detected head or store if it is a better detection headCenter[headCenter.size() - 1] = center; headRadius[headRadius.size() - 1] = radius; } } } } if (headRadius[headRadius.size() - 1] == 0) { headRadius[headRadius.size() - 1] = 10; } } } } // draw bodies and heads //cv::Mat bodiesHeads = cv::Mat::zeros(image.size(), CV_8UC3); for (int i = 0; i < bodies.size(); i++) { // draw body cv::Scalar colour = cv::Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); drawContours(foreground, objectContours, bodies[i], colour, 2, 8, objectHierarchy, 0, cv::Point()); circle(foreground, headCenter[i], (int)headRadius[i], colour, 2, 8, 0); // body bounding box cv::RotatedRect bodyRect; bodyRect = cv::minAreaRect(cv::Mat(objectContours[bodies[i]])); // output cout << imageNum; cout << "," << headCenter[i].x << "," << headCenter[i].y << "," << headRadius[i]; // head info cout << "," << bodyRect.center.x << "," << bodyRect.center.y; cout << "," << cv::contourArea(objectContours[bodies[i]]); cout << endl; // output points cv::Mat point(2, 1, CV_32FC1); point.at<float>(0) = headCenter[i].x; point.at<float>(1) = headCenter[i].y; points.push_back(point); } // increment frame counter numFrames++; cv::imshow("Original", image); //cv::imshow("Hue", imageHSVSlices[0]); //cv::imshow("Saturation", imageHSVSlices[1]); //cv::imshow("Value", imageHSVSlices[2]); cv::imshow("fgMask", fgMask); cv::imshow("Foreground", foreground); cv::imshow("Canny", imageCanny); cv::imshow("WeightMap", weightMap); cv::imshow("Gradient Image", imageGradient); cv::imshow("Weighted-Gradient Image", weightedGradient); //cv::imshow("Contours", imageContours); cv::imshow("Body & Head", bodiesHeads); cvWaitKey(delay); //5 return points; }