glm::dvec4 StdMaterial::lightAttenuation(const Raycast& ray) const { double opa = opacity(ray.origin); if(opa >= 1.0) { // Fully pigmented -> no propagation return glm::dvec4(0.0); } else if(opa <= 0.0) { // Never hits a pigment return glm::dvec4(1.0); } else { glm::dvec3 col = color(ray.origin); double scatterRate = 1 / (1 / opa - 1); glm::dvec3 accumulation( ray.limit * scatterRate ); return glm::dvec4(cellar::fast_pow(col, accumulation), 1.0); } }
void analyzeVideo(const std::string& folder, const Camera& calibrated_camera, float label_width) { // Start with a single hypotheses of the cube. std::vector<ProbabalisticCube> cube_hypotheses; cube_hypotheses.push_back(ProbabalisticCube()); for (int frame_i = 0;;) { printf("Frame %i\n", frame_i); char buf[1024]; sprintf(buf, "%s/frame%05d.png", folder.c_str(), frame_i); cv::Mat3b img = cv::imread(buf, cv::IMREAD_COLOR); if (img.empty()) { break; } const size_t num_hypotheses_before = cube_hypotheses.size(); printf("Num hypotheses before: %lu\n", num_hypotheses_before); cube_hypotheses = predict(cube_hypotheses); const size_t num_hypotheses_after = cube_hypotheses.size(); printf("Num hypotheses after: %lu\n", num_hypotheses_after); printf("Brancing factor: %f\n", double(num_hypotheses_after) / num_hypotheses_before); const size_t max_hypotheses = 216; if (num_hypotheses_after > max_hypotheses) { const size_t pruned_num = num_hypotheses_after - max_hypotheses; const double removed_percentage = pruned_num * 100.0 / num_hypotheses_after; printf("Pruning to %lu hypotheses, removing %lu (%.1f%%) hypotheses.\n", max_hypotheses, pruned_num, removed_percentage); } prune(cube_hypotheses, max_hypotheses); printf("Most likely cubes:\n"); for (int i = 0; i < cube_hypotheses.size() && i < 5; ++i) { const ProbabalisticCube& cube = cube_hypotheses[i]; const std::string permutation = cube.cube_permutation.to_String(); const double likelihood_percent = exp(cube.log_likelihood) * 100.0; printf("%d: %s %3.5f%%\n", i, permutation.c_str(), likelihood_percent); } std::vector<LabelContour> labels = findLabelContours(img, 12, true); std::vector<std::vector<cv::Point2f>> detected_corners = findLabelCorners(labels); std::vector<Camera> all_camera_candidates; for (const auto& corners : detected_corners) { std::vector<Camera> cameras = predictCameraPosesForLabel(calibrated_camera, corners, label_width); all_camera_candidates.insert(all_camera_candidates.end(), cameras.begin(), cameras.end()); } std::vector<double> camera_scores; camera_scores.reserve(all_camera_candidates.size()); { cv::Mat1f accumulation(img.size(), 0.f); for (const auto& cam : all_camera_candidates) { cv::Mat1f contribution(img.size(), 0.f); std::vector<cv::Point2f> predicted_corners = projectCubeCorners(cam, label_width); double score = scorePredictedCorners(predicted_corners, detected_corners); camera_scores.push_back(score); for (int i = 0; i < predicted_corners.size(); i += 4) { std::vector<cv::Point> corners = { predicted_corners[i + 0], predicted_corners[i + 1], predicted_corners[i + 2], predicted_corners[i + 3], }; cv::polylines(contribution, corners, true, cv::Scalar(score * score)); } accumulation += contribution; } double minval; double maxval; cv::minMaxLoc(accumulation, &minval, &maxval); cv::imshow("accumulation", accumulation / maxval); } if (!camera_scores.empty()) { std::vector<double> sorted_camera_scores = camera_scores; std::sort(sorted_camera_scores.begin(), sorted_camera_scores.end()); std::reverse(sorted_camera_scores.begin(), sorted_camera_scores.end()); printf("Min score: %f max score: %f\n", sorted_camera_scores.back(), sorted_camera_scores.front()); for (int i = 0; i < sorted_camera_scores.size() && i < 5; ++i) { double score = sorted_camera_scores[i]; printf("#%d score: %f\n", i + 1, score); } } if (!all_camera_candidates.empty()) { const size_t index = std::distance(camera_scores.begin(), std::max_element(camera_scores.begin(), camera_scores.end())); printf("detected_corners size: %lu index: %lu\n", detected_corners.size(), index); const Camera& cam = all_camera_candidates[index]; std::vector<cv::Point2f> predicted_corners = projectCubeCorners(cam, label_width); cv::Mat3b canvas = img * 0.25f; for (int i = 0; i < predicted_corners.size(); i += 4) { std::vector<cv::Point> corners = { predicted_corners[i + 0], predicted_corners[i + 1], predicted_corners[i + 2], predicted_corners[i + 3], }; cv::polylines(canvas, corners, true, cv::Scalar(0, 0, 255)); } { std::vector<cv::Point> corners = { detected_corners[index / 9][0], detected_corners[index / 9][1], detected_corners[index / 9][2], detected_corners[index / 9][3], }; cv::polylines(canvas, corners, true, cv::Scalar(255, 0, 255)); } cv::imshow("predicted labels", canvas); } { cv::Mat3b canvas = img * 0.25f; drawLabels(canvas, labels, cv::Scalar(255, 255, 255)); for (const auto& corners : detected_corners) { cv::polylines(canvas, cast<cv::Point>(corners), true, cv::Scalar(0, 0, 255)); for (size_t i = 0; i < corners.size(); ++i) { char text[12]; sprintf(text, "%lu", i); cv::putText(canvas, text, corners[i], cv::FONT_HERSHEY_PLAIN, 1, cv::Scalar(0, 0, 255)); } } cv::imshow("detected labels", canvas); } if (int key = cv::waitKey(0) & 255) { if (key == 27) { break; // stop by pressing ESC } if (key == 32) // space { ++frame_i; } if (key == 83) // right arrow { ++frame_i; } if (key == 82) // up arrow { } if (key == 81) // left arrow { --frame_i; } if (key == 84) // down arrow { } if (key != 255) { printf("Key: %d\n", key); fflush(stdout); } } } }