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.<br>
<br>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<br>
<br>Program received signal SIGSEGV, Segmentation fault.<br>0x0804ae63 in detectorsolis(_IplImage&, std::vector<Segment2D, std::allocator<Segment2D> >*) ()<br><br>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.<br>
<br>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.<br><br>El código es el siguiente:<br><br>=====================<br><br>#include <iostream><br>
#include "cv.h"<br>#include "highgui.h"<br><br>#define G_SQUARE(a) ((a)*(a))<br><br>typedef struct {<br> float x;<br> float y;<br> float h;<br>} HPoint2D;<br><br>typedef struct {<br> HPoint2D start;<br>
HPoint2D end;<br> int type;<br> int isValid;<br>} Segment2D;<br><br>void detectorsolis(IplImage &image, std::vector<Segment2D> *segments);<br>double distanceBetweenPoints2D(int x1, int y1, int x2, int y2);<br>
double distanceBetweenPoints2D(double x1, double y1, double x2, double y2);<br><br>int main() {<br> IplImage *image;<br> image = cvLoadImage("puerta.jpg",CV_LOAD_IMAGE_UNCHANGED);<br> cvNamedWindow("Line Detection Algorithm");<br>
std::vector<Segment2D> segments;<br><br> detectorsolis(*image, &segments);<br><br> cvShowImage("Line Detection Algorithm", image);<br> cvWaitKey();<br><br> cvReleaseImage(&image);<br>
cvDestroyWindow("Line Detection Algorithm");<br>}<br><br>const int CASES_OFFSET = 5;<br><br>const int solis_cases[][11] =<br> { { 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8 },<br> { 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8 }, { 6, 6, 6, 6, 7, 7, 7, 8,<br>
8, 8, 8 }, { 5, 5, 6, 6, 7, 7, 7, 8, 8, 1, 1 }, { 5, 5,<br> 5, 5, 0, 0, 0, 1, 1, 1, 1 }, { 5, 5, 5, 5, 0, 0, 0, 1,<br> 1, 1, 1 }, { 5, 5, 5, 5, 0, 0, 0, 1, 1, 1, 1 }, { 5, 5,<br>
4, 4, 3, 3, 3, 2, 2, 1, 1 }, { 4, 4, 4, 4, 3, 3, 3, 2,<br> 2, 2, 2 }, { 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2 }, { 4, 4,<br> 4, 3, 3, 3, 3, 3, 2, 2, 2 } };<br>
<br>void detectorsolis(IplImage &image, std::vector<Segment2D> *segments) {<br> IplImage *IplTmp1, *IplTmp2, *IplBlack, *IplLaplace;<br> CvPoint pstart, pend;<br> CvMemStorage *storage;<br> CvSeq* contour = NULL;<br>
int i, i_jump = 6;<br> int ThressValue = 30;<br> int diff_x, diff_y;<br> CvPoint *WholePointArray;<br> const int min_size_contour = 30;<br> CvScalar color;<br> Segment2D mySegment;<br> int type, current_type;<br>
int num_frag, min_frags = 3, counter = 0;<br> double max_distance;<br> bool first, debug = false;<br><br> IplTmp1 = cvCreateImage(cvSize(image.width, image.height), IPL_DEPTH_8U, 1);<br> IplTmp2 = cvCreateImage(cvSize(image.width, image.height), IPL_DEPTH_8U, 1);<br>
IplLaplace = cvCreateImage(cvSize(image.width, image.height), IPL_DEPTH_16S, 1);<br> storage = cvCreateMemStorage(0);<br><br> /*Convert to Gray Image*/<br> cvCvtColor(&image, IplTmp1, CV_RGB2GRAY);<br><br>
/*Normalize image*/<br> cvNormalize(IplTmp1, IplTmp1, 0, 255, CV_MINMAX);<br><br> // Make a average filtering<br> cvSmooth(IplTmp1, IplTmp2, CV_BLUR, 3, 3); //-> OK<br> //cvSmooth(IplTmp1,IplTmp2,CV_BLUR,1,1);<br>
<br> //Laplace<br> cvLaplace(IplTmp2, IplLaplace, 3);<br> cvConvertScale(IplLaplace, IplTmp1);<br><br> /*Perform a binary threshold*/<br> cvThreshold(IplTmp1, IplTmp2, ThressValue, 255, CV_THRESH_BINARY);<br>
<br> /*Find contours*/<br> cvFindContours(IplTmp2, storage, &contour, sizeof(CvContour), CV_RETR_LIST,<br> CV_LINK_RUNS); //->OK<br> //cvFindContours(IplTmp2, storage, &contour, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_NONE);<br>
<br> /*Run through found coutours*/<br> while (contour != NULL) {<br> /*Check length*/<br> if (contour->total >= min_size_contour) {<br> /*Convert to array*/<br> WholePointArray = (CvPoint *) malloc(<br>
contour->total * sizeof(CvPoint));<br> cvCvtSeqToArray(contour, WholePointArray, CV_WHOLE_SEQ);<br><br> i = 0;<br> first = true;<br><br> while ((i < (contour->total - (i_jump - 1)))) {<br>
<br> counter++;<br><br> /*Get current segment*/<br> pstart.x = WholePointArray[(int) i].x;<br> pstart.y = WholePointArray[(int) i].y;<br> pend.x = WholePointArray[(int) (i + i_jump - 1)].x;<br>
pend.y = WholePointArray[(int) (i + i_jump - 1)].y;<br><br> /*Calculate type*/<br> diff_x = pstart.x - pend.x;<br> diff_y = pstart.y - pend.y;<br> type =<br>
solis_cases[diff_x + CASES_OFFSET][diff_y + CASES_OFFSET];<br><br> if (debug) {<br> /*Visual portions*/<br> if (type == 0)<br> color = CV_RGB(255,255,255);<br>
else if (type == 1)<br> color = CV_RGB(255,255,0);<br> else if (type == 2)<br> color = CV_RGB(0,255,255);<br> else if (type == 3)<br>
color = CV_RGB(255,0,0);<br> else if (type == 4)<br> color = CV_RGB(0,255,0);<br> else if (type == 5)<br> color = CV_RGB(0,0,255);<br>
else if (type == 6)<br> color = CV_RGB(255,0,255);<br> else if (type == 7)<br> color = CV_RGB(0,128,128);<br> else if (type == 8)<br>
color = CV_RGB(128,128,0);<br><br> /*Draw line with orientation*/<br> cvLine(IplBlack, pstart, pend, color, 2, CV_AA, 0);<br> } else {<br> if (first) {<br>
if (type != 0) {<br> mySegment.start.x = pstart.x;<br> mySegment.start.y = pstart.y;<br> mySegment.start.h = (float) counter;<br>
mySegment.end.x = pend.x;<br> mySegment.end.y = pend.y;<br> mySegment.end.h = (float) counter;<br> mySegment.type = type;<br>
first = false;<br> current_type = type;<br> num_frag = 1;<br> }<br> } else {<br> /*Check type threshold*/<br>
if (current_type == type /*|| type == 0*/) {<br> /*Save current end*/<br> mySegment.end.x = pend.x;<br> mySegment.end.y = pend.y;<br>
mySegment.end.h = (float) counter;<br> num_frag++;<br> } else {<br> /*Save current segment if length is enough*/<br>
if (num_frag >= min_frags)<br> segments->push_back(mySegment);<br> first = true;<br> }<br> }<br>
}<br><br> i += i_jump;<br> }<br><br> /*Save the last one*/<br> if (!first && num_frag >= min_frags)<br> segments->push_back(mySegment);<br>
<br> free(WholePointArray);<br> }<br><br> contour = contour->h_next;<br> }<br><br> max_distance = (double) (i_jump * min_frags);<br><br> /*Merge consecutive fragments*/<br> std::vector<Segment2D>::iterator it1 = segments->begin();<br>
while (it1 != segments->end()) {<br> /*Compare with next one*/<br> std::vector<Segment2D>::iterator it2 = it1;<br> it2++;<br> if (it2 != segments->end()) {<br> if ((*it1).type == (*it2).type<br>
&& (*it2).start.h - (*it1).end.h <= min_frags) {<br> if (distanceBetweenPoints2D((*it2).start.x,<br> (*it2).start.y, (*it1).end.x, (*it1).end.y)<br> <= max_distance) {<br>
(*it1).end.x = (*it2).end.x;<br> (*it1).end.y = (*it2).end.y;<br> (*it1).end.h = (*it2).end.h;<br> segments->erase(it2);<br> continue;<br>
}<br> }<br> }<br><br> it1++;<br> }<br><br> /*Reset .h values*/<br> for (std::vector<Segment2D>::iterator it_s = segments->begin();<br> it_s != segments->end(); it_s++) {<br>
(*it_s).start.h = 1.0;<br> (*it_s).end.h = 1.0;<br> }<br><br> /*Clean up*/<br> cvReleaseImage(&IplTmp1);<br> cvReleaseImage(&IplTmp2);<br> cvClearMemStorage(storage); //Free contour<br>
cvReleaseMemStorage(&storage);<br><br> if (debug)<br> cvReleaseImage(&IplBlack);<br>}<br><br>double distanceBetweenPoints2D(int x1, int y1, int x2, int y2)<br>{<br> return sqrt(G_SQUARE(x2-x1) + G_SQUARE(y2-y1));<br>
}<br><br>double distanceBetweenPoints2D(double x1, double y1, double x2, double y2)<br>{<br> return sqrt(G_SQUARE(x2-x1) + G_SQUARE(y2-y1));<br>}<br><br><br>