00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00024
00025 #include <qvdta/qvcontour.h>
00026
00027
00028
00029
00030
00031
00032
00034 const char coorX8Connect[8] = { 0, 1, 1, 1, 0, -1, -1, -1 };
00035 const char coorY8Connect[8] = { -1, -1, 0, 1, 1, 1, 0, -1 };
00036 const char coorX4Connect[4] = { 0, 1, 0, -1, };
00037 const char coorY4Connect[4] = { -1, 0, 1, 0, };
00038 const char coorX4Diag[8] = { 1, 1, -1, -1 };
00039 const char coorY4Diag[8] = { -1, 1, 1, -1 };
00041
00042
00044 QVPolyline getConnectedSetBorderContourThresholdFromBorderPoint(const QVImage<uChar> &image, const int startPointX, const int startPointY, const uChar threshold)
00045 {
00046 QVPolyline lista;
00047
00048 lista.closed = true;
00049 lista.append(QPoint(startPointX, startPointY));
00050
00051 QVIMAGE_INIT_READ(uChar,image);
00052 QRect roi = image.getROI();
00053
00054 Q_ASSERT_X(roi.contains(startPointX, startPointY), "getContourThresholdFromBorderPoint", "start point out of image ROI");
00055 Q_ASSERT_X(QVIMAGE_PIXEL(image, startPointX, startPointY, 0) >= threshold, "getContourThresholdFromBorderPoint", "start point is not contained in a connected set");
00056
00057
00058
00059 uChar searchDir = 128, numOuterPixels = 0;
00060 for (int i = 0; i<8; i++)
00061 {
00062 int x = startPointX +coorX8Connect[i], y = startPointY +coorY8Connect[i];
00063 if (!roi.contains(x, y))
00064 {
00065 numOuterPixels++;
00066 searchDir = i;
00067 }
00068 else if (QVIMAGE_PIXEL(image, x, y,0) < threshold)
00069 {
00070 numOuterPixels++;
00071 searchDir = i;
00072 }
00073 }
00074
00075
00076 Q_ASSERT_X(searchDir < 8, "getContourThresholdFromBorderPoint", "start point is inside the set, not in the border");
00077
00078
00079 if (numOuterPixels == 8)
00080 return lista;
00081
00082
00083 int sumSearchDir = 0, actualPointX = startPointX, actualPointY = startPointY;
00084 while (true)
00085 {
00086
00087 uChar d;
00088 int nextPointX, nextPointY;
00089 for (d = 0; d < 8; d++)
00090 {
00091 searchDir = (searchDir+1)%8;
00092 nextPointX = actualPointX + coorX8Connect[searchDir];
00093 nextPointY = actualPointY + coorY8Connect[searchDir];
00094 if (roi.contains(nextPointX, nextPointY))
00095 if ( (QVIMAGE_PIXEL(image, nextPointX, nextPointY,0) >= threshold) )
00096 break;
00097 }
00098
00099 sumSearchDir += d - 3;
00100
00101 actualPointX = nextPointX;
00102 actualPointY = nextPointY;
00103
00104 if ( QVIMAGE_PIXEL(image, actualPointX, actualPointY,0) < threshold )
00105 break;
00106
00107 if ( startPointX == actualPointX && startPointY == actualPointY)
00108 break;
00109
00110 lista.append(QPoint(actualPointX, actualPointY));
00111 searchDir = searchDir + 4;
00112 }
00113
00114 lista.direction = (sumSearchDir >= 0);
00115 return lista;
00116 }
00118
00119 QVPolyline getConnectedSetBorderContourThreshold(const QVImage<uChar> &image, const QPoint startPoint, const uChar threshold)
00120 {
00121 QVIMAGE_INIT_READ(uChar,image);
00122 const QRect roi = image.getROI();
00123
00124 int col = startPoint.x(), row = startPoint.y();
00125
00126 if (QVIMAGE_PIXEL(image, col, row,0) < threshold)
00127 return QVPolyline();
00128
00129 while (roi.contains(col+1, row))
00130 {
00131 if ( QVIMAGE_PIXEL(image, col+1, row,0) < threshold )
00132 break;
00133 col++;
00134 }
00135
00136 return getConnectedSetBorderContourThresholdFromBorderPoint(image, col, row, threshold);
00137 }
00138
00139 QList<QVPolyline> getConnectedSetBorderContoursThreshold(const QVImage <uChar> &image, const uChar threshold)
00140 {
00141 qDebug() << "getPolylinesThreshold()";
00142 QVImage<uChar> mask(image.getCols()+1, image.getRows()+1);
00143 Set(mask,0);
00144
00145 QVIMAGE_INIT_READ(uChar,image);
00146 QVIMAGE_INIT_WRITE(uChar,mask);
00147
00148 QRect roi = image.getROI();
00149
00150 QList<QVPolyline> polylineList;
00151
00152
00153 for (int row = roi.y(); row < roi.y() + roi.height(); row++)
00154 for (int col = roi.x(); col < roi.y() + roi.width(); col++)
00155 {
00156
00157 if (QVIMAGE_PIXEL(image, col, row,0) >= threshold)
00158 {
00159
00160 if ( !QVIMAGE_PIXEL(mask, col, row,0) )
00161 {
00162 QVPolyline lista = getConnectedSetBorderContourThresholdFromBorderPoint(image, col, row, threshold);
00163 draw(mask, lista, true, true);
00164 polylineList.append(lista);
00165 }
00166
00167
00168 while (roi.contains(col+1, row))
00169 {
00170 if ( QVIMAGE_PIXEL(image, col+1, row,0) < threshold )
00171 break;
00172 col++;
00173 }
00174
00175
00176 if ( !QVIMAGE_PIXEL(mask, col, row,0) )
00177 {
00178 QVPolyline lista = getConnectedSetBorderContourThresholdFromBorderPoint(image, col, row, threshold);
00179 draw(mask, lista, true, true);
00180 polylineList.append(lista);
00181 }
00182 }
00183
00184 }
00185 qDebug() << "getPolylinesThreshold():"<< polylineList.size() << "contours obtained";
00186 qDebug() << "getPolylinesThreshold() <~ return";
00187 return polylineList;
00188 }
00189
00191
00192 QVPolyline getLineContourThreshold4Connectivity(QVImage<uChar> &image, const QPoint point, QVPolyline &polyline, const uChar threshold, bool reverse)
00193 {
00194 const uInt cols = image.getCols(), rows = image.getRows();
00195 QVIMAGE_INIT_WRITE(uChar, image);
00196
00197 uInt lastDir = 666, coorX = point.x(), coorY = point.y();
00198
00199 qDebug() << "\tContour: new contour";
00200
00201 while(true)
00202 {
00203 qDebug() << "\tContour:\tAppending point (" << coorX << ", " << coorY << ")";
00204 if (reverse)
00205 polyline.prepend(QPoint(coorX, coorY));
00206 else
00207 polyline.append(QPoint(coorX, coorY));
00208
00209 QVIMAGE_PIXEL(image, coorX, coorY, 0) = 0;
00210
00211 uInt dir;
00212 int newCoorX, newCoorY;
00213 for (dir = 0; dir < 4; dir++)
00214 {
00215 newCoorX = coorX + coorX4Connect[dir];
00216 newCoorY = coorY + coorY4Connect[dir];
00217
00218
00219 if ( (newCoorX < 0) || (newCoorY < 0) || (newCoorX >= cols) || (newCoorY >= rows) )
00220 continue;
00221
00222
00223 if ( (QVIMAGE_PIXEL(image, newCoorX, newCoorY, 0) >= threshold) && (lastDir != dir) )
00224 break;
00225 }
00226
00227 if (dir == 4) break;
00228
00229 coorX = newCoorX;
00230 coorY = newCoorY;
00231 lastDir = (dir+2)%4;
00232 }
00233
00234 return polyline;
00235 }
00236
00237 QList<QVPolyline> getLineContoursThreshold4Connectivity(const QVImage<uChar> &image, const uChar threshold)
00238 {
00239 const uInt cols = image.getCols(), rows = image.getRows();
00240 QVImage<uChar> clone = image;
00241
00242 QList<QVPolyline> polylineList;
00243
00244
00245 for(uInt col = 0; col < cols; col++)
00246 for(uInt row = 0; row < rows; row++)
00247 {
00248 QVIMAGE_INIT_READ(uChar, clone);
00249
00250 if ( (QVIMAGE_PIXEL(clone, col, row, 0) < threshold) )
00251 continue;
00252
00253
00254 QVPolyline polyline;
00255
00256
00257 getLineContourThreshold4Connectivity(clone, QPoint(col, row), polyline, threshold, false);
00258
00259
00260 uInt dir;
00261 int newCoorX, newCoorY;
00262 for (dir = 0; dir < 4; dir++)
00263 {
00264 newCoorX = col + coorX4Connect[dir];
00265 newCoorY = row + coorY4Connect[dir];
00266
00267
00268 if ( (newCoorX < 0) || (newCoorY < 0) || (newCoorX >= cols) || (newCoorY >= rows) )
00269 continue;
00270
00271
00272 if ( (clone(newCoorX, newCoorY) >= threshold) )
00273 break;
00274 }
00275
00276
00277 if (dir != 4)
00278 getLineContourThreshold4Connectivity(clone, QPoint(newCoorX, newCoorY), polyline, threshold, true);
00279
00280
00281 polylineList.append(polyline);
00282 }
00283
00284 return polylineList;
00285 }
00286
00288
00289 QVPolyline getLineContourThreshold8Connectivity(QVImage<uChar> &image, const QPoint point, QVPolyline &polyline, const uChar threshold, bool reverse)
00290 {
00291 const uInt cols = image.getCols(), rows = image.getRows();
00292 QVIMAGE_INIT_WRITE(uChar, image);
00293
00294 uInt lastDir = 666, coorX = point.x(), coorY = point.y();
00295
00296 qDebug() << "\tContour: new contour";
00297
00298 bool continueCond = true;
00299 while(continueCond)
00300 {
00301 qDebug() << "\tContour:\tAppending point (" << coorX << ", " << coorY << ")";
00302 if (reverse)
00303 polyline.prepend(QPoint(coorX, coorY));
00304 else
00305 polyline.append(QPoint(coorX, coorY));
00306
00307 QVIMAGE_PIXEL(image, coorX, coorY, 0) = 0;
00308
00309
00310 uInt dir;
00311 int newCoorX, newCoorY;
00312 for (dir = 0; dir < 4; dir++)
00313 {
00314 newCoorX = coorX + coorX4Connect[dir];
00315 newCoorY = coorY + coorY4Connect[dir];
00316
00317
00318 if ( (newCoorX < 0) || (newCoorY < 0) || (newCoorX >= cols) || (newCoorY >= rows) )
00319 continue;
00320
00321
00322 if ( (QVIMAGE_PIXEL(image, newCoorX, newCoorY, 0) >= threshold) && (lastDir != dir) )
00323 break;
00324 }
00325
00326 if (dir == 4)
00327 {
00328
00329 uInt dir;
00330 int newCoorX, newCoorY;
00331 for (dir = 0; dir < 4; dir++)
00332 {
00333 newCoorX = coorX + coorX4Diag[dir];
00334 newCoorY = coorY + coorY4Diag[dir];
00335
00336
00337 if ( (newCoorX < 0) || (newCoorY < 0) || (newCoorX >= cols) || (newCoorY >= rows) )
00338 continue;
00339
00340
00341 if ( (QVIMAGE_PIXEL(image, newCoorX, newCoorY, 0) >= threshold) && (lastDir != dir) )
00342 break;
00343 }
00344 if (dir == 4) break;
00345
00346 coorX = newCoorX;
00347 coorY = newCoorY;
00348 lastDir = (dir+2)%4;
00349 }
00350 else {
00351 coorX = newCoorX;
00352 coorY = newCoorY;
00353 lastDir = (dir+2)%4;
00354 }
00355 }
00356
00357 return polyline;
00358 }
00359
00360 QList<QVPolyline> getLineContoursThreshold8Connectivity(const QVImage<uChar> &image, const uChar threshold)
00361 {
00362 const uInt cols = image.getCols(), rows = image.getRows();
00363 QVImage<uChar> clone = image;
00364
00365 QList<QVPolyline> polylineList;
00366
00367
00368 for(uInt col = 0; col < cols; col++)
00369 for(uInt row = 0; row < rows; row++)
00370 {
00371 QVIMAGE_INIT_READ(uChar, clone);
00372
00373 if ( (QVIMAGE_PIXEL(clone, col, row, 0) < threshold) )
00374 continue;
00375
00376
00377 QVPolyline polyline;
00378
00379
00380 getLineContourThreshold8Connectivity(clone, QPoint(col, row), polyline, threshold, false);
00381
00382
00383 uInt dir;
00384 int newCoorX, newCoorY;
00385 for (dir = 0; dir < 4; dir++)
00386 {
00387 newCoorX = col + coorX4Connect[dir];
00388 newCoorY = row + coorY4Connect[dir];
00389
00390
00391 if ( (newCoorX < 0) || (newCoorY < 0) || (newCoorX >= cols) || (newCoorY >= rows) )
00392 continue;
00393
00394
00395 if ( (clone(newCoorX, newCoorY) >= threshold) )
00396 break;
00397 }
00398
00399
00400 if (dir != 4)
00401 getLineContourThreshold8Connectivity(clone, QPoint(newCoorX, newCoorY), polyline, threshold, true);
00402 else {
00403
00404 uInt dir;
00405 int newCoorX, newCoorY;
00406 for (dir = 0; dir < 4; dir++)
00407 {
00408 newCoorX = col + coorX4Diag[dir];
00409 newCoorY = row + coorY4Diag[dir];
00410
00411
00412 if ( (newCoorX < 0) || (newCoorY < 0) || (newCoorX >= cols) || (newCoorY >= rows) )
00413 continue;
00414
00415
00416 if ( (clone(newCoorX, newCoorY) >= threshold) )
00417 break;
00418 }
00419
00420
00421 if (dir != 4)
00422 getLineContourThreshold8Connectivity(clone, QPoint(newCoorX, newCoorY), polyline, threshold, true);
00423 }
00424
00425
00426 polylineList.append(polyline);
00427 }
00428
00429 return polylineList;
00430 }
00431