00001 #include "AutoFocus.h"
00002 #include "Lens.h"
00003 #include "Frame.h"
00004
00005 namespace FCam {
00006
00007 AutoFocus::AutoFocus(Lens *l) : lens(l), state(IDLE) {}
00008
00009 void AutoFocus::startSweep() {
00010 if (!lens) return;
00011 state = HOMING;
00012
00013 lens->setFocus(lens->farFocus());
00014 stats.clear();
00015 }
00016
00017
00018 void AutoFocus::update(Frame::Ptr f) {
00019 if (state == FOCUSED || state == IDLE) return;
00020
00021 if (state == SETTING) {
00022 if (!lens->focusChanging()) {
00023 state = FOCUSED;
00024 }
00025 return;
00026 }
00027
00028
00029 const Lens::Tags *lensTags = f->tags(lens);
00030 if (!lensTags) return;
00031 if (!f->sharpness.valid) return;
00032
00033 Stats s;
00034 s.position = lensTags->focus;
00035 s.sharpness = 0;
00036 for (int sy = 0; sy < f->sharpness.size.height; sy++) {
00037 for (int sx = 0; sx < f->sharpness.size.width; sx++) {
00038 s.sharpness += f->sharpness(sx, sy) >> 10;
00039 }
00040 }
00041 stats.push_back(s);
00042
00043
00044 if (state == HOMING && !lens->focusChanging()) {
00045 lens->setFocus(lens->nearFocus(), (lens->nearFocus() - lens->farFocus())*2);
00046 state = SWEEPING;
00047 return;
00048 }
00049
00050 if (state == SWEEPING && stats.size() > 4) {
00051 bool gettingWorse = true;
00052
00053
00054
00055
00056 for (size_t i = stats.size()-1; i > stats.size()-4; i--) {
00057 if (stats[i].position < stats[i-1].position ||
00058 (stats[i].sharpness*101)/100 > stats[i-1].sharpness) {
00059 gettingWorse = false;
00060 break;
00061 }
00062 }
00063
00064
00065 if (!lens->focusChanging() || gettingWorse) {
00066 Stats best = stats[0];
00067 for (size_t i = 1; i < stats.size(); i++) {
00068 if (stats[i].sharpness > best.sharpness) best = stats[i];
00069 }
00070
00071 lens->setFocus(best.position);
00072 state = SETTING;
00073 stats.clear();
00074 return;
00075 }
00076 }
00077
00078 if (state == SETTING && !lens->focusChanging()) {
00079 state = FOCUSED;
00080 return;
00081 }
00082
00083 }
00084
00085
00086
00087 }