00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "ImageRegionFinder.h"
00017
00018 #include <QImage>
00019 #include <cmath>
00020 #include <stack>
00021 #include <iostream>
00022
00023 ImageRegionFinder::ImageRegionFinder()
00024 {
00025 }
00026
00027 ImageRegionFinder::~ImageRegionFinder()
00028 {
00029 }
00030
00031 QRect
00032 ImageRegionFinder::findRegionExtents(QImage *image, QPoint origin) const
00033 {
00034 int w = image->width(), h = image->height();
00035
00036 QImage visited(w, h, QImage::Format_Mono);
00037 visited.fill(0);
00038
00039 std::stack<QPoint> s;
00040 s.push(origin);
00041
00042 int xmin = origin.x();
00043 int xmax = xmin;
00044 int ymin = origin.y();
00045 int ymax = ymin;
00046
00047 QRgb opix = image->pixel(origin);
00048
00049 while (!s.empty()) {
00050
00051 QPoint p = s.top();
00052 s.pop();
00053
00054 visited.setPixel(p, 1);
00055
00056 int x = p.x(), y = p.y();
00057
00058 if (x < xmin) xmin = x;
00059 if (x > xmax) xmax = x;
00060
00061 if (y < ymin) ymin = y;
00062 if (y > ymax) ymax = y;
00063
00064 std::stack<QPoint> neighbours;
00065
00066 int similarNeighbourCount = 0;
00067
00068 for (int dx = -1; dx <= 1; ++dx) {
00069 for (int dy = -1; dy <= 1; ++dy) {
00070
00071 if ((dx != 0 && dy != 0) ||
00072 (dx == 0 && dy == 0))
00073 continue;
00074
00075 if (x + dx < 0 || x + dx >= w ||
00076 y + dy < 0 || y + dy >= h)
00077 continue;
00078
00079 if (visited.pixelIndex(x + dx, y + dy) != 0)
00080 continue;
00081
00082 if (!similar(opix, image->pixel(x + dx, y + dy)))
00083 continue;
00084
00085 neighbours.push(QPoint(x + dx, y + dy));
00086 ++similarNeighbourCount;
00087 }
00088 }
00089
00090 if (similarNeighbourCount >= 2) {
00091 while (!neighbours.empty()) {
00092 s.push(neighbours.top());
00093 neighbours.pop();
00094 }
00095 }
00096 }
00097
00098 return QRect(xmin, ymin, xmax - xmin, ymax - ymin);
00099 }
00100
00101 bool
00102 ImageRegionFinder::similar(QRgb a, QRgb b) const
00103 {
00104 if (b == qRgb(0, 0, 0) || b == qRgb(255, 255, 255)) {
00105
00106
00107 return false;
00108 }
00109
00110 float ar = float(qRed(a) / 255.f);
00111 float ag = float(qGreen(a) / 255.f);
00112 float ab = float(qBlue(a) / 255.f);
00113 float amag = sqrtf(ar * ar + ag * ag + ab * ab);
00114 float thresh = amag / 2;
00115
00116 float dr = float(qRed(a) - qRed(b)) / 255.f;
00117 float dg = float(qGreen(a) - qGreen(b)) / 255.f;
00118 float db = float(qBlue(a) - qBlue(b)) / 255.f;
00119 float dist = sqrtf(dr * dr + dg * dg + db * db);
00120
00121
00122
00123 return (dist < thresh);
00124 }
00125