Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ExampleRefineContour.cpp

Example Contour Refinement Usage: ExampleRefineContour SegmentedImage ColorImage ContourImage

Author
MIP
/*
This file is part of the BIAS library (Basic ImageAlgorithmS).
Copyright (C) 2003-2009 (see file CONTACT for details)
Multimediale Systeme der Informationsverarbeitung
Institut fuer Informatik
Christian-Albrechts-Universitaet Kiel
BIAS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
BIAS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with BIAS; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
@example ExampleRefineContour.cpp
@relates ContourDetectorSimple
@brief Example Contour Refinement
Usage: ExampleRefineContour SegmentedImage ColorImage ContourImage
@ingroup g_examples
@author MIP
*/
#include <Filter/FilterNTo2N.hh>
#include <Filter/GradientSobel3x3.hh>
#include <Filter/GradientGauss.hh>
#include <Filter/GradientGaussAsymmetric.hh>
#include <Base/Image/ImageIO.hh>
#include <Base/Image/ImageConvert.hh>
#include <Base/Debug/TimeMeasure.hh>
#include <math.h>
#include <Base/ImageUtils/ImageDraw.hh>
#include "FeatureDetector/ContourDetectorSimple.hh"
#include <Base/Common/BIASpragma.hh>
using namespace BIAS;
using namespace std;
#define InputImageType unsigned char
#define OutputImageType float
int main(int argc, char *argv[])
{
if(argc < 4){
cerr << "usage: "<< argv[0] << "SegmentedImage ColorImage ContourImage" << endl;
exit(0);
}
Image<float> segIm;
Image<float>contourImg;
// read images
ImageIO::Load(argv[1],segIm);
ImageIO::Load(argv[2],im);
// first search contours of image
cont.SetBackground(0);
std::vector<BIASContour> contour;
cont.Detect(segIm, contour);
// calculate gradients of image
//grad = &gsobel3x3;
grad = &ggauss;
grad->SetBorderHandling(FilterBase<InputImageType,
OutputImageType>::TBH_valid);
gsobel3x3.Filter(im, gx, gy, g);
float** data = g.GetImageDataArray();
// search refinements
BIASContour ct = contour[0];
BIASContour ct_copy = contour[0];
// die Contour ablaufen
int dSearchLength = 20;
double start_x, start_y, end_x, end_y;
BIAS::Vector2<double> pointMiddle;
for(unsigned int i = 0; i < ct.length; i++){
// read startpoint of line
pointS = ct.contourPixel[i];
start_x = pointS[0];
start_y = pointS[1];
// read middle point (this one will maybe refined)
pointMiddle = ct.contourPixel[(i+2)%ct.length];
int offset = (i+4)%ct.length;
// read endpoint of line
pointE = ct.contourPixel[offset];
end_x = pointE[0];
end_y = pointE[1];
//freeman = ct.freemanCode[i];
//double dx = end_x - start_x;
//double dy = end_y - start_y;
// calc distance
double distance = sqrt(pow((end_x - start_x),2) +
pow((end_y - start_y),2));
double PvectorXone = (end_y - start_y);
double PvectorYone = -(end_x - start_x);
double coefficient = dSearchLength / distance;
double normX = coefficient*PvectorXone;
//double normY = coefficient*PvectorYone;
//cout << start_x << " , " << start_y << ", Normale: " << PvectorXone << "," << PvectorYone << endl;
// die Normale nach aussen laufen
int x,y;
int fk = 1;
bool found = false;
// search outside of the contour
while((normX+pointMiddle[0]) - (pointMiddle[0] + PvectorXone*fk) > 0 ){
x = pointMiddle[0] + PvectorXone*fk;
y = pointMiddle[1] + PvectorYone*fk;
if(data[y][x] > 12.0){
// move point
ct_copy.contourPixel[i][0]=x;
ct_copy.contourPixel[i][1]=y;
found = true;
break;
}
fk++;
}
// search inside of the contour
fk=-1;
if(!found){
while((pointMiddle[0]-normX) - (pointMiddle[0] + PvectorXone*fk) > 0 ){
x = pointMiddle[0] + PvectorXone*fk;
y = pointMiddle[1] + PvectorYone*fk;
if(x >=0 && y >=0){
if(data[y][x] > 12.0){
// move point
ct_copy.contourPixel[i][0]=x;
ct_copy.contourPixel[i][1]=y;
found = true;
break;
}
}else{
break;
}
fk--;
}
}
}
contourImg.Init(segIm.GetWidth(), segIm.GetHeight(),3);
// draw contour before refinement
for (unsigned int k=0;k<ct.length;k++){
contourImg.SetPixel(100,100,100,
(unsigned int)ct.contourPixel[k][0],
(unsigned int)ct.contourPixel[k][1]);
}
// draw contour after refinement
for (unsigned int k=0;k<ct_copy.length;k++){
contourImg.SetPixel(255,255,255,
(unsigned int)ct_copy.contourPixel[k][0],
(unsigned int)ct_copy.contourPixel[k][1]);
}
// connect points of contour with lines
float col[3];
col[0] = 255;
col[1] = 255;
col[2] = 255;
for (unsigned int k=0;k<ct_copy.length-1;k++){
ImageDraw<float>::Line(contourImg,(unsigned int) ct_copy.contourPixel[k][0],
(unsigned int) ct_copy.contourPixel[k][1],
(unsigned int) ct_copy.contourPixel[k+1][0],
(unsigned int) ct_copy.contourPixel[k+1][1],
col,
1.0);
}
// save contour
ImageIO::Save(argv[3], contourImg);
}