00001 #include <math.h>
00002
00003 #include "FCam/AutoFocus.h"
00004 #include "FCam/Lens.h"
00005 #include "FCam/Frame.h"
00006
00007 #include "Debug.h"
00008
00009 namespace FCam {
00010
00011 AutoFocus::AutoFocus(Lens *l, Rect r) : lens(l), state(IDLE), rect(r) {}
00012
00013 void AutoFocus::startSweep() {
00014 if (!lens) return;
00015 state = HOMING;
00016
00017 lens->setFocus(lens->farFocus());
00018 stats.clear();
00019 }
00020
00021
00022 void AutoFocus::update(const Frame &f) {
00023 if (state == FOCUSED || state == IDLE) return;
00024
00025 if (state == SETTING) {
00026 if (!lens->focusChanging()) {
00027 state = FOCUSED;
00028 }
00029 return;
00030 }
00031
00032
00033 if (!f.sharpness().valid()) return;
00034
00035
00036 int minSx = 0;
00037 int minSy = 0;
00038 int maxSx = f.sharpness().size().width-1;
00039 int maxSy = f.sharpness().size().height-1;
00040 float w = f.shot().image.width();
00041 float h = f.shot().image.height();
00042 if (rect.width > 0 && rect.height > 0) {
00043 minSx = int(rect.x * f.sharpness().size().width / w + 0.5);
00044 minSy = int(rect.y * f.sharpness().size().height / h + 0.5);
00045 maxSx = int((rect.x + rect.width) * f.sharpness().size().width / w + 0.5);
00046 maxSy = int((rect.y + rect.height) * f.sharpness().size().height / h + 0.5);
00047 if (maxSx >= f.sharpness().size().width) maxSx = f.sharpness().size().width-1;
00048 if (maxSy >= f.sharpness().size().height) maxSy = f.sharpness().size().height-1;
00049 if (minSx >= f.sharpness().size().width) minSx = f.sharpness().size().width-1;
00050 if (minSy >= f.sharpness().size().height) minSy = f.sharpness().size().height-1;
00051 if (minSx < 0) minSx = 0;
00052 if (minSy < 0) minSy = 0;
00053 if (maxSx < 0) maxSx = 0;
00054 if (maxSy < 0) maxSy = 0;
00055 }
00056
00057 Stats s;
00058 s.position = f["lens.focus"];
00059 s.sharpness = 0;
00060 for (int sy = minSy; sy <= maxSy; sy++) {
00061 for (int sx = minSx; sx <= maxSx; sx++) {
00062 s.sharpness += f.sharpness()(sx, sy) >> 10;
00063 }
00064 }
00065 stats.push_back(s);
00066 dprintf(4, "Focus position %f, sharpness %d\n", s.position, s.sharpness);
00067
00068 if (state == HOMING && !lens->focusChanging()) {
00069
00070 if (fabs(s.position - lens->farFocus()) < 0.01) {
00071 lens->setFocus(lens->nearFocus(), (lens->nearFocus() - lens->farFocus()));
00072 state = SWEEPING;
00073 return;
00074 }
00075 }
00076
00077 if (state == SWEEPING && stats.size() > 4) {
00078 bool gettingWorse = true;
00079
00080
00081
00082
00083 for (size_t i = stats.size()-1; i > stats.size()-4; i--) {
00084 if (stats[i].position < stats[i-1].position ||
00085 (stats[i].sharpness*101)/100 > stats[i-1].sharpness) {
00086 gettingWorse = false;
00087 break;
00088 }
00089 }
00090
00091
00092 if (!lens->focusChanging() || gettingWorse) {
00093 Stats best = stats[0];
00094 for (size_t i = 1; i < stats.size(); i++) {
00095 if (stats[i].sharpness > best.sharpness) best = stats[i];
00096 }
00097
00098 lens->setFocus(best.position);
00099 state = SETTING;
00100 stats.clear();
00101 return;
00102 }
00103 }
00104
00105 if (state == SETTING && !lens->focusChanging()) {
00106 state = FOCUSED;
00107 return;
00108 }
00109
00110 }
00111
00112 }