Lower the exposure when we see lots of bright pixels.
This is deterministic, so we will see the field repeatably. When this
was random, we were randomly getting different targets depending on
which mode it was in.
Change-Id: I3d8dddeadab9527b3824b0bfbf25c88ecff9de22
diff --git a/y2019/vision/target_finder.cc b/y2019/vision/target_finder.cc
index f6e5ac4..83d4a01 100644
--- a/y2019/vision/target_finder.cc
+++ b/y2019/vision/target_finder.cc
@@ -26,6 +26,14 @@
});
}
+int TargetFinder::PixelCount(BlobList *imgs) {
+ int num_pixels = 0;
+ for (RangeImage &img : *imgs) {
+ num_pixels += img.npixels();
+ }
+ return num_pixels;
+}
+
// Filter blobs on size.
void TargetFinder::PreFilter(BlobList *imgs) {
imgs->erase(
@@ -577,13 +585,11 @@
}
bool TargetFinder::TestExposure(const std::vector<IntermediateResult> &results,
- int *desired_exposure) {
+ int pixel_count, int *desired_exposure) {
// TODO(ben): Add these values to config file.
constexpr double low_dist = 0.8;
- constexpr double high_dist = 2.0;
constexpr int low_exposure = 60;
- constexpr int mid_exposure = 300;
- constexpr int high_exposure = 500;
+ constexpr int mid_exposure = 200;
bool needs_update = false;
if (results.size() > 0) {
@@ -591,10 +597,11 @@
// based on the distance to that target.
// First result should always be the closest target.
if (results[0].extrinsics.z < low_dist) {
+ LOG(INFO) << "Low exposure";
*desired_exposure = low_exposure;
- } else if (results[0].extrinsics.z > high_dist) {
- *desired_exposure = high_exposure;
+ close_bucket_ = 4;
} else {
+ LOG(INFO) << "Mid exposure";
*desired_exposure = mid_exposure;
}
if (*desired_exposure != current_exposure_) {
@@ -602,32 +609,23 @@
current_exposure_ = *desired_exposure;
}
} else {
- // We don't see a target, but part of the problem might
- // be the exposure setting. Lets try changing it and see
- // if things get better.
- const int offset = std::rand() % 10;
-
- // At random with 3/X probability try a higher or lower.
- if (offset == 0) {
- if (low_exposure != current_exposure_) {
- needs_update = true;
- current_exposure_ = low_exposure;
- *desired_exposure = low_exposure;
- }
- } else if (offset == 1) {
- if (mid_exposure != current_exposure_) {
- needs_update = true;
- current_exposure_ = mid_exposure;
- *desired_exposure = mid_exposure;
- }
- } else if (offset == 2) {
- if (high_exposure != current_exposure_) {
- needs_update = true;
- current_exposure_ = high_exposure;
- *desired_exposure = high_exposure;
+ close_bucket_ = ::std::max(0, close_bucket_ - 1);
+ // It's been a while since we saw a target.
+ if (close_bucket_ == 0) {
+ if (pixel_count > 6000) {
+ if (low_exposure != current_exposure_) {
+ needs_update = true;
+ current_exposure_ = low_exposure;
+ *desired_exposure = low_exposure;
+ }
+ } else {
+ if (mid_exposure != current_exposure_) {
+ needs_update = true;
+ current_exposure_ = mid_exposure;
+ *desired_exposure = mid_exposure;
+ }
}
}
- // If one of our cases is not hit don't change anything.
}
return needs_update;
}
diff --git a/y2019/vision/target_finder.h b/y2019/vision/target_finder.h
index 0f1575c..d54dc2d 100644
--- a/y2019/vision/target_finder.h
+++ b/y2019/vision/target_finder.h
@@ -41,6 +41,8 @@
// Value against which we threshold.
static uint8_t GetThresholdValue() { return 100; }
+ int PixelCount(BlobList *imgs);
+
// filter out obvious or durranged blobs.
void PreFilter(BlobList *imgs);
@@ -72,7 +74,7 @@
bool verbose);
bool TestExposure(const std::vector<IntermediateResult> &results,
- int *desired_exposure);
+ int pixel_count, int *desired_exposure);
// Get the local overlay for debug if we are doing that.
aos::vision::PixelLinesOverlay *GetOverlay() { return &overlay_; }
@@ -108,6 +110,8 @@
size_t frame_count_;
size_t valid_result_count_;
+ int close_bucket_ = 0;
+
int current_exposure_ = 0;
};
diff --git a/y2019/vision/target_sender.cc b/y2019/vision/target_sender.cc
index db33419..b7fed9a 100644
--- a/y2019/vision/target_sender.cc
+++ b/y2019/vision/target_sender.cc
@@ -202,6 +202,8 @@
aos::vision::ImageFormat fmt{640, 480};
aos::vision::BlobList imgs =
aos::vision::FindBlobs(thresholder.Threshold(fmt, data.data(), 120));
+ const int num_pixels = finder.PixelCount(&imgs);
+ LOG(INFO) << "Number pixels: " << num_pixels;
finder.PreFilter(&imgs);
LOG(INFO) << "Blobs: " << imgs.size();
@@ -263,7 +265,7 @@
LOG(INFO) << "Results: " << results.size();
int desired_exposure;
- if (finder.TestExposure(results, &desired_exposure)) {
+ if (finder.TestExposure(results, num_pixels, &desired_exposure)) {
camera0->SetExposure(desired_exposure);
}