void ExtractFeaturesFromEachFrame(const std::string & video_source, std::vector<Features> features_collection, const cv::Size & window_size, bool scale) { std::srand(std::time(0)); cv::VideoCapture video(video_source); if(!video.isOpened()) return; cv::HOGDescriptor hog; hog.winSize=window_size; cv::Mat frame; cv::Mat extracted_frame; Features features; while(video.read(frame)) { if(scale) cv::resize(frame, extracted_frame, window_size); else { // Extract frame cv::Rect patch; patch.width=window_size.width; patch.height=window_size.height; patch.x=std::rand()%(frame.cols-window_size.width); patch.y=std::rand()%(frame.rows-window_size.height); extracted_frame=((frame)(patch)).clone(); features_collection.push_back(Features((features_collection.size()==0?0:features_collection.front().size()))); ComputeFeatures(extracted_frame, features_collection.back(), window_size); } features.clear(); } }
int main (int argc, char** argv) { PointCloudType::Ptr cloud(new PointCloudType); PointCloudType::PointType p0(1,2,3); cloud->push_back(p0); // Call without normals { ComputeFeatures(cloud); } // Call with normals { PointCloudWithNormalsType::Ptr cloudWithNormals(new PointCloudWithNormalsType); copyPointCloud(*cloud, *cloudWithNormals); ComputeFeatures(cloudWithNormals); } return 0; }
void ComputeFeatures(PointCloudType::Ptr cloud) { // Compute the normals pcl::NormalEstimation<PointCloudType::PointType, PointCloudWithNormalsType::PointType> normalEstimation; normalEstimation.setInputCloud (cloud); typedef pcl::search::KdTree<PointCloudType::PointType> TreeType; TreeType::Ptr tree (new TreeType); normalEstimation.setSearchMethod (tree); PointCloudWithNormalsType::Ptr cloudWithNormals (new PointCloudWithNormalsType); normalEstimation.setRadiusSearch (0.03); normalEstimation.compute (*cloudWithNormals); copyPointCloud(*cloud, *cloudWithNormals); std::cout << cloudWithNormals->points[0].x << std::endl; ComputeFeatures(cloudWithNormals); }
// Extracts Tesseract features and appends them to the features vector. // Startpt to lastpt, inclusive, MUST have the same src_outline member, // which may be nullptr. The vector from lastpt to its next is included in // the feature extraction. Hidden edges should be excluded by the caller. // If force_poly is true, the features will be extracted from the polygonal // approximation even if more accurate data is available. static void ExtractFeaturesFromRun( const EDGEPT* startpt, const EDGEPT* lastpt, const DENORM& denorm, double feature_length, bool force_poly, GenericVector<INT_FEATURE_STRUCT>* features) { const EDGEPT* endpt = lastpt->next; const C_OUTLINE* outline = startpt->src_outline; if (outline != nullptr && !force_poly) { // Detailed information is available. We have to normalize only from // the root_denorm to denorm. const DENORM* root_denorm = denorm.RootDenorm(); int total_features = 0; // Get the features from the outline. int step_length = outline->pathlength(); int start_index = startpt->start_step; // pos is the integer coordinates of the binary image steps. ICOORD pos = outline->position_at_index(start_index); // We use an end_index that allows us to use a positive increment, but that // may be beyond the bounds of the outline steps/ due to wrap-around, to // so we use % step_length everywhere, except for start_index. int end_index = lastpt->start_step + lastpt->step_count; if (end_index <= start_index) end_index += step_length; LLSQ prev_points; LLSQ prev_dirs; FCOORD prev_normed_pos = outline->sub_pixel_pos_at_index(pos, start_index); denorm.NormTransform(root_denorm, prev_normed_pos, &prev_normed_pos); LLSQ points; LLSQ dirs; FCOORD normed_pos(0.0f, 0.0f); int index = GatherPoints(outline, feature_length, denorm, root_denorm, start_index, end_index, &pos, &normed_pos, &points, &dirs); while (index <= end_index) { // At each iteration we nominally have 3 accumulated sets of points and // dirs: prev_points/dirs, points/dirs, next_points/dirs and sum them // into sum_points/dirs, but we don't necessarily get any features out, // so if that is the case, we keep accumulating instead of rotating the // accumulators. LLSQ next_points; LLSQ next_dirs; FCOORD next_normed_pos(0.0f, 0.0f); index = GatherPoints(outline, feature_length, denorm, root_denorm, index, end_index, &pos, &next_normed_pos, &next_points, &next_dirs); LLSQ sum_points(prev_points); // TODO(rays) find out why it is better to use just dirs and next_dirs // in sum_dirs, instead of using prev_dirs as well. LLSQ sum_dirs(dirs); sum_points.add(points); sum_points.add(next_points); sum_dirs.add(next_dirs); bool made_features = false; // If we have some points, we can try making some features. if (sum_points.count() > 0) { // We have gone far enough from the start. Make a feature and restart. FCOORD fit_pt = sum_points.mean_point(); FCOORD fit_vector = MeanDirectionVector(sum_points, sum_dirs, prev_normed_pos, normed_pos); // The segment to which we fit features is the line passing through // fit_pt in direction of fit_vector that starts nearest to // prev_normed_pos and ends nearest to normed_pos. FCOORD start_pos = prev_normed_pos.nearest_pt_on_line(fit_pt, fit_vector); FCOORD end_pos = normed_pos.nearest_pt_on_line(fit_pt, fit_vector); // Possible correction to match the adjacent polygon segment. if (total_features == 0 && startpt != endpt) { FCOORD poly_pos(startpt->pos.x, startpt->pos.y); denorm.LocalNormTransform(poly_pos, &start_pos); } if (index > end_index && startpt != endpt) { FCOORD poly_pos(endpt->pos.x, endpt->pos.y); denorm.LocalNormTransform(poly_pos, &end_pos); } int num_features = ComputeFeatures(start_pos, end_pos, feature_length, features); if (num_features > 0) { // We made some features so shuffle the accumulators. prev_points = points; prev_dirs = dirs; prev_normed_pos = normed_pos; points = next_points; dirs = next_dirs; made_features = true; total_features += num_features; } // The end of the next set becomes the end next time around. normed_pos = next_normed_pos; } if (!made_features) { // We didn't make any features, so keep the prev accumulators and // add the next ones into the current. points.add(next_points); dirs.add(next_dirs); } } } else { // There is no outline, so we are forced to use the polygonal approximation. const EDGEPT* pt = startpt; do { FCOORD start_pos(pt->pos.x, pt->pos.y); FCOORD end_pos(pt->next->pos.x, pt->next->pos.y); denorm.LocalNormTransform(start_pos, &start_pos); denorm.LocalNormTransform(end_pos, &end_pos); ComputeFeatures(start_pos, end_pos, feature_length, features); } while ((pt = pt->next) != endpt); } }