blob: 073f8e5b23c1ed85b32e0b9057f2ed76db9f8578 [file] [log] [blame]
#include <iostream>
#include <Eigen/Dense>
#include "aos/vision/blob/move_scale.h"
#include "aos/vision/blob/stream_view.h"
#include "aos/vision/blob/transpose.h"
#include "aos/vision/debug/debug_framework.h"
#include "aos/vision/math/vector.h"
#include "y2017/vision/target_finder.h"
using aos::vision::BlobList;
using aos::vision::ImageFormat;
using aos::vision::ImageRange;
using aos::vision::RangeImage;
namespace y2017::vision {
BlobList RenderTargetListShifted(const std::vector<TargetComponent> &list) {
BlobList out;
for (const auto &entity : list) {
out.emplace_back(entity.RenderShifted());
}
return out;
}
RangeImage TargetComponent::RenderShifted() const {
std::vector<std::vector<ImageRange>> out_range_list;
int y = 0;
double max_y = -b / (2 * a);
double parab_off = max_y * max_y * a + max_y * b;
RangeImage t_img = Transpose(*img);
for (const auto &row : t_img) {
int off = -(y * y * a + y * b - parab_off);
// int off = 0;
// fprintf(stderr, "off: %d %d\n", off, y);
std::vector<ImageRange> row_out;
for (const ImageRange &range : row) {
row_out.emplace_back(ImageRange{off + range.st, off + range.ed});
}
++y;
out_range_list.emplace_back(std::move(row_out));
}
return RangeImage(t_img.min_y(), std::move(out_range_list));
}
class FilterHarnessExample : public aos::vision::FilterHarness {
public:
aos::vision::RangeImage Threshold(aos::vision::ImagePtr image) override {
return finder_.Threshold(image);
}
void InstallViewer(aos::vision::BlobStreamViewer *viewer) override {
viewer_ = viewer;
viewer_->SetScale(0.5);
overlays_.push_back(&overlay_);
overlays_.push_back(finder_.GetOverlay());
viewer_->view()->SetOverlays(&overlays_);
}
bool HandleBlobs(BlobList imgs, ImageFormat /*fmt*/) override {
// reset for next drawing cycle
for (auto &overlay : overlays_) {
overlay->Reset();
}
// Remove bad blobs.
finder_.PreFilter(imgs);
// calculate each component/
std::vector<TargetComponent> target_component_list =
finder_.FillTargetComponentList(imgs);
DrawComponents(target_component_list);
// Put the compenents together into targets and pick the best.
Target final_target;
bool found_target =
finder_.FindTargetFromComponents(target_component_list, &final_target);
// BlobList newImg = RenderTargetListShifted(target_component_list);
if (viewer_) {
viewer_->DrawBlobList(imgs, {0, 0, 255});
}
if (found_target) {
BlobList list;
list.emplace_back(*(final_target.comp1.img));
list.emplace_back(*(final_target.comp2.img));
viewer_->DrawBlobList(list, {0, 255, 0});
overlay_.DrawCross(final_target.screen_coord, 25, {255, 255, 255});
}
// No targets.
return found_target;
}
void DrawComponents(const std::vector<TargetComponent> comp) {
for (const TargetComponent &t : comp) {
aos::vision::ImageBBox bbox;
GetBBox(*(t.img), &bbox);
overlay_.DrawBBox(bbox, {255, 0, 0});
overlay_.StartNewProfile();
for (int i = 0; i < bbox.maxx - bbox.minx; i += 10) {
double y0 = t.a * i * i + t.b * i + t.c_0;
double y1 = t.a * i * i + t.b * i + t.c_1;
overlay_.AddPoint(aos::vision::Vector<2>(i + t.mini, y0), {255, 0, 0});
overlay_.AddPoint(aos::vision::Vector<2>(i + t.mini, y1), {255, 0, 0});
}
}
}
private:
// implementation of the filter pipeline.
TargetFinder finder_;
aos::vision::BlobStreamViewer *viewer_ = nullptr;
aos::vision::PixelLinesOverlay overlay_;
std::vector<aos::vision::OverlayBase *> overlays_;
};
} // namespace y2017::vision
int main(int argc, char **argv) {
y2017::vision::FilterHarnessExample filter_harness;
aos::vision::DebugFrameworkMain(argc, argv, &filter_harness,
aos::vision::CameraParams());
}