[Jderobot-dev] problemas con algoritmo de Solis
Julio Guillén
julio.guillen en gmail.com
Mar Mar 27 12:05:59 CEST 2012
Hola amigos, os escribo porque estoy teniendo un fallo raro al tratar de
usar Solis. Me he creado un sencillo programa para poder utilizar imágenes
con solis y poder comparar resultados tras optimizarlo para mi caso
concreto. Quiero adelantar que estoy usando la versión 2.0.0 de OpenCv y
que ya he sido capaz de utilizar este algoritmo en un componente propio.
El caso es que me he creado un pequeño proyecto en C++ y me he traído todo
lo necesario para poder usarlo de manera independiente. El programa me
compila perfectamente, pero a la hora de ejecutar me da fallo de violación
de segmento. Empleando GDB me dice que el fallo está en detectorsolis
Program received signal SIGSEGV, Segmentation fault.
0x0804ae63 in detectorsolis(_IplImage&, std::vector<Segment2D,
std::allocator<Segment2D> >*) ()
más concretamente cuando hago cvCreateImage de IplTmp1. El algoritmo de
solis está exactamente igual que el de la librería visionlib, y he sido
capaz de utilizarlo sin problemas en mi componente. Pero ahora me da fallo
y creo que es por tipos deprecados. No entiendo por qué antes me funcionaba
perfecto y ahora me da los fallos.
A ver si me podeis ayudar, y mis disculpas si es un fallo evidente. La
verdad llevo tanto con esto que no se por donde continuar.
El código es el siguiente:
=====================
#include <iostream>
#include "cv.h"
#include "highgui.h"
#define G_SQUARE(a) ((a)*(a))
typedef struct {
float x;
float y;
float h;
} HPoint2D;
typedef struct {
HPoint2D start;
HPoint2D end;
int type;
int isValid;
} Segment2D;
void detectorsolis(IplImage &image, std::vector<Segment2D> *segments);
double distanceBetweenPoints2D(int x1, int y1, int x2, int y2);
double distanceBetweenPoints2D(double x1, double y1, double x2, double y2);
int main() {
IplImage *image;
image = cvLoadImage("puerta.jpg",CV_LOAD_IMAGE_UNCHANGED);
cvNamedWindow("Line Detection Algorithm");
std::vector<Segment2D> segments;
detectorsolis(*image, &segments);
cvShowImage("Line Detection Algorithm", image);
cvWaitKey();
cvReleaseImage(&image);
cvDestroyWindow("Line Detection Algorithm");
}
const int CASES_OFFSET = 5;
const int solis_cases[][11] =
{ { 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8 },
{ 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8 }, { 6, 6, 6, 6, 7, 7, 7,
8,
8, 8, 8 }, { 5, 5, 6, 6, 7, 7, 7, 8, 8, 1, 1 }, {
5, 5,
5, 5, 0, 0, 0, 1, 1, 1, 1 }, { 5, 5, 5, 5, 0, 0, 0,
1,
1, 1, 1 }, { 5, 5, 5, 5, 0, 0, 0, 1, 1, 1, 1 }, {
5, 5,
4, 4, 3, 3, 3, 2, 2, 1, 1 }, { 4, 4, 4, 4, 3, 3, 3,
2,
2, 2, 2 }, { 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2 }, {
4, 4,
4, 3, 3, 3, 3, 3, 2, 2, 2 } };
void detectorsolis(IplImage &image, std::vector<Segment2D> *segments) {
IplImage *IplTmp1, *IplTmp2, *IplBlack, *IplLaplace;
CvPoint pstart, pend;
CvMemStorage *storage;
CvSeq* contour = NULL;
int i, i_jump = 6;
int ThressValue = 30;
int diff_x, diff_y;
CvPoint *WholePointArray;
const int min_size_contour = 30;
CvScalar color;
Segment2D mySegment;
int type, current_type;
int num_frag, min_frags = 3, counter = 0;
double max_distance;
bool first, debug = false;
IplTmp1 = cvCreateImage(cvSize(image.width, image.height),
IPL_DEPTH_8U, 1);
IplTmp2 = cvCreateImage(cvSize(image.width, image.height),
IPL_DEPTH_8U, 1);
IplLaplace = cvCreateImage(cvSize(image.width, image.height),
IPL_DEPTH_16S, 1);
storage = cvCreateMemStorage(0);
/*Convert to Gray Image*/
cvCvtColor(&image, IplTmp1, CV_RGB2GRAY);
/*Normalize image*/
cvNormalize(IplTmp1, IplTmp1, 0, 255, CV_MINMAX);
// Make a average filtering
cvSmooth(IplTmp1, IplTmp2, CV_BLUR, 3, 3); //-> OK
//cvSmooth(IplTmp1,IplTmp2,CV_BLUR,1,1);
//Laplace
cvLaplace(IplTmp2, IplLaplace, 3);
cvConvertScale(IplLaplace, IplTmp1);
/*Perform a binary threshold*/
cvThreshold(IplTmp1, IplTmp2, ThressValue, 255, CV_THRESH_BINARY);
/*Find contours*/
cvFindContours(IplTmp2, storage, &contour, sizeof(CvContour),
CV_RETR_LIST,
CV_LINK_RUNS); //->OK
//cvFindContours(IplTmp2, storage, &contour, sizeof(CvContour),
CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
/*Run through found coutours*/
while (contour != NULL) {
/*Check length*/
if (contour->total >= min_size_contour) {
/*Convert to array*/
WholePointArray = (CvPoint *) malloc(
contour->total * sizeof(CvPoint));
cvCvtSeqToArray(contour, WholePointArray, CV_WHOLE_SEQ);
i = 0;
first = true;
while ((i < (contour->total - (i_jump - 1)))) {
counter++;
/*Get current segment*/
pstart.x = WholePointArray[(int) i].x;
pstart.y = WholePointArray[(int) i].y;
pend.x = WholePointArray[(int) (i + i_jump - 1)].x;
pend.y = WholePointArray[(int) (i + i_jump - 1)].y;
/*Calculate type*/
diff_x = pstart.x - pend.x;
diff_y = pstart.y - pend.y;
type =
solis_cases[diff_x + CASES_OFFSET][diff_y +
CASES_OFFSET];
if (debug) {
/*Visual portions*/
if (type == 0)
color = CV_RGB(255,255,255);
else if (type == 1)
color = CV_RGB(255,255,0);
else if (type == 2)
color = CV_RGB(0,255,255);
else if (type == 3)
color = CV_RGB(255,0,0);
else if (type == 4)
color = CV_RGB(0,255,0);
else if (type == 5)
color = CV_RGB(0,0,255);
else if (type == 6)
color = CV_RGB(255,0,255);
else if (type == 7)
color = CV_RGB(0,128,128);
else if (type == 8)
color = CV_RGB(128,128,0);
/*Draw line with orientation*/
cvLine(IplBlack, pstart, pend, color, 2, CV_AA, 0);
} else {
if (first) {
if (type != 0) {
mySegment.start.x = pstart.x;
mySegment.start.y = pstart.y;
mySegment.start.h = (float) counter;
mySegment.end.x = pend.x;
mySegment.end.y = pend.y;
mySegment.end.h = (float) counter;
mySegment.type = type;
first = false;
current_type = type;
num_frag = 1;
}
} else {
/*Check type threshold*/
if (current_type == type /*|| type == 0*/) {
/*Save current end*/
mySegment.end.x = pend.x;
mySegment.end.y = pend.y;
mySegment.end.h = (float) counter;
num_frag++;
} else {
/*Save current segment if length is enough*/
if (num_frag >= min_frags)
segments->push_back(mySegment);
first = true;
}
}
}
i += i_jump;
}
/*Save the last one*/
if (!first && num_frag >= min_frags)
segments->push_back(mySegment);
free(WholePointArray);
}
contour = contour->h_next;
}
max_distance = (double) (i_jump * min_frags);
/*Merge consecutive fragments*/
std::vector<Segment2D>::iterator it1 = segments->begin();
while (it1 != segments->end()) {
/*Compare with next one*/
std::vector<Segment2D>::iterator it2 = it1;
it2++;
if (it2 != segments->end()) {
if ((*it1).type == (*it2).type
&& (*it2).start.h - (*it1).end.h <= min_frags) {
if (distanceBetweenPoints2D((*it2).start.x,
(*it2).start.y, (*it1).end.x, (*it1).end.y)
<= max_distance) {
(*it1).end.x = (*it2).end.x;
(*it1).end.y = (*it2).end.y;
(*it1).end.h = (*it2).end.h;
segments->erase(it2);
continue;
}
}
}
it1++;
}
/*Reset .h values*/
for (std::vector<Segment2D>::iterator it_s = segments->begin();
it_s != segments->end(); it_s++) {
(*it_s).start.h = 1.0;
(*it_s).end.h = 1.0;
}
/*Clean up*/
cvReleaseImage(&IplTmp1);
cvReleaseImage(&IplTmp2);
cvClearMemStorage(storage); //Free contour
cvReleaseMemStorage(&storage);
if (debug)
cvReleaseImage(&IplBlack);
}
double distanceBetweenPoints2D(int x1, int y1, int x2, int y2)
{
return sqrt(G_SQUARE(x2-x1) + G_SQUARE(y2-y1));
}
double distanceBetweenPoints2D(double x1, double y1, double x2, double y2)
{
return sqrt(G_SQUARE(x2-x1) + G_SQUARE(y2-y1));
}
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: http://gsyc.escet.urjc.es/pipermail/jde-developers/attachments/20120327/66777b7b/attachment.htm
More information about the Jde-developers
mailing list