/* Filename: main.cpp Author: Jocelyn Miller Date: August 21, 2003 This is the main file for parsing the XML files that are outputted by Yi for the Content-based Image-retrieval database. How to run: main *.xml */ #include #include #include #include #include #include #include #include #include #include #include "Histogram_element.h" #include "Constants.h" #include "Color.h" #include "Image.h" #include "Matrix.h" #include "Html_cluster.h" XERCES_CPP_NAMESPACE_USE using namespace std; // list to hold all of the images vector *ls = new vector(); /** * Name: getImage * * Purpose: to see if an image with the same name has been evaluated previously */ Image *getImage(char *fileName) { vector::iterator iter = ls->begin(); bool contained = false; for(unsigned int j=0;jsize();j++) { if ((*iter)->getName() == fileName) { contained = true; break; } iter++; } Image *i; if(contained) i = *iter; else { i = new Image(fileName); ls->push_back(i); } return i; } /** * Name: parsePolyRegion * * Purpose: gets all the information for the region of a polygon and puts it into the Image * including ellipse into that approximates the region, and more specific contour info * * Notes: passes in a label for the name of the ellipse region because in some files it is * "polygon-region" and in others it is "region-info" */ Region_info *parsePolyRegion(DOMElement *start, char *ellipse_region_label) { DOMNodeList *poly_ls = start->getElementsByTagName(XMLString::transcode(ellipse_region_label)); if(poly_ls->getLength() == 0) cerr << "BIG PROBLEM -- NO ELLIPSE REGIONS" << endl; DOMElement *ellipse = (DOMElement *)(poly_ls->item(0)); Ellipse_region *e = new Ellipse_region(); // getting all the atttributes from the ellipse region double cen_x = strtod(XMLString::transcode(ellipse->getAttribute(XMLString::transcode("m_centroid-x"))), NULL); double cen_y = strtod(XMLString::transcode(ellipse->getAttribute(XMLString::transcode("m_centroid-y"))), NULL); double maj_ang = strtod(XMLString::transcode(ellipse->getAttribute(XMLString::transcode("m_maj-angle"))), NULL); double maj_len = strtod(XMLString::transcode(ellipse->getAttribute(XMLString::transcode("m_maj-length"))), NULL); double min_ang = strtod(XMLString::transcode(ellipse->getAttribute(XMLString::transcode("m_min-angle"))), NULL); double min_len = strtod(XMLString::transcode(ellipse->getAttribute(XMLString::transcode("m_min-length"))), NULL); double moment_x = strtod(XMLString::transcode(ellipse->getAttribute(XMLString::transcode("m_moment-x"))), NULL); double moment_y = strtod(XMLString::transcode(ellipse->getAttribute(XMLString::transcode("m_moment-y"))), NULL); double moment_xy = strtod(XMLString::transcode(ellipse->getAttribute(XMLString::transcode("m_moment-xY"))), NULL); double size = strtod(XMLString::transcode(ellipse->getAttribute(XMLString::transcode("m_size"))), NULL); double width = strtod(XMLString::transcode(ellipse->getAttribute(XMLString::transcode("img-width"))), NULL); double height = strtod(XMLString::transcode(ellipse->getAttribute(XMLString::transcode("img-height"))), NULL); //setting all the attributes for the ellipse region e->setCenter(new Point(cen_x, cen_y)); e->setMajAngle(maj_ang); e->setMinAngle(min_ang); e->setMajLength(maj_len); e->setMinLength(min_len); e->setSize(size); e->setMomentX_Y_XY(moment_x, moment_y, moment_xy); e->setWidth(width); e->setHeight(height); DOMNodeList *polys = start->getElementsByTagName(XMLString::transcode("polygon-region")); double area; // gets the parser to the polygon-region info portion of the XML // (includes the hole-flags and contours) if(polys->getLength() == 1) { DOMElement *polygon = (DOMElement *)(polys->item(0)); area = strtod(XMLString::transcode(polygon->getAttribute(XMLString::transcode("area"))), NULL); // some XML files have 2 polygon-region labels--in that case, we want the // second region with that label } else if(polys->getLength() == 2) { DOMElement *polygon = (DOMElement *)(polys->item(1)); area = strtod(XMLString::transcode(polygon->getAttribute(XMLString::transcode("area"))), NULL); // there should be at most 2 polygon-region labelled portions } else { area = -1; cerr << "problem with extracting area" << endl; } DOMNodeList *holes = start->getElementsByTagName(XMLString::transcode("hole-flag")); DOMNodeList *contours = start->getElementsByTagName(XMLString::transcode("contour")); // need a hole label for each contour description if (holes->getLength() != contours->getLength()) cerr << "ERR: The number of holes and contours don't match up" << endl; Region_info *info = new Region_info(e, area); // marks the holes appropriately for(XMLSize_t n = 0;ngetLength();n++) { Contour_info *cont = new Contour_info(); if(strcmp(XMLString::transcode((holes->item(n))->getTextContent()), "true") == 0 ) { cont->makeHole(); } // for each contour, gets the x and y values DOMNodeList *Xs = ((DOMElement *)(contours->item(n)))->getElementsByTagName(XMLString::transcode("x")); DOMNodeList *Ys = ((DOMElement *)(contours->item(n)))->getElementsByTagName(XMLString::transcode("y")); // must have an equal number of x and y coords if(Xs->getLength() != Ys->getLength()) { cerr << "ERR: The number of x and y coords is not equal!" << endl; } // sets the points for each contour for(XMLSize_t m =0; mgetLength();m++) { double new_x = strtod(XMLString::transcode((Xs->item(m))->getTextContent()), NULL); double new_y = strtod(XMLString::transcode((Ys->item(m))->getTextContent()), NULL); cont->addPoint(new Point(new_x, new_y)); } info->addContourRegion(cont); } return info; } /** * Name: parseTexture * * Purpose: get all texture attributes into the Image object */ void parseTexture(Image *i, DOMDocument *doc, DOMElement *root) { double width = strtod(XMLString::transcode(root->getAttribute(XMLString::transcode("image-width"))), NULL); double height = strtod(XMLString::transcode(root->getAttribute(XMLString::transcode("image-height"))), NULL); double scale = strtod(XMLString::transcode(root->getAttribute(XMLString::transcode("scale"))), NULL); Texture_regions *regs = new Texture_regions(width, height, scale); i->setTextureRegions(regs); DOMNodeList *children = root->getElementsByTagName(XMLString::transcode("texture-polygon-region")); XMLSize_t len = children->getLength(); for(XMLSize_t j = 0;jitem(j)); DOMNodeList *texture = kid->getElementsByTagName(XMLString::transcode("texture-mean")); if(texture->getLength() != 12) cerr << "ERR: The number of texture Gabor coefficients values isn't 12!" << endl; double *gabor = new double[texture->getLength()]; for(XMLSize_t m=0; mgetLength(); m++) { gabor[m] = strtod(XMLString::transcode((texture->item(m))->getTextContent()), NULL); } Texture *t = new Texture(gabor, texture->getLength()); DOMNodeList *covariance = kid->getElementsByTagName(XMLString::transcode("texture-covariance")); if(covariance->getLength() != 144) cerr << "ERR: The number of texture covariance values isn't 144!" << endl; double *covs = new double[covariance->getLength()]; for(XMLSize_t n = 0; n< covariance->getLength(); n++) { covs[n] = strtod(XMLString::transcode((covariance->item(n))->getTextContent()), NULL); } Texture_covariance *cov = new Texture_covariance(covs, covariance->getLength()); Texture_region *reg = new Texture_region(t, cov); regs->addRegion(reg); Region_info *info = parsePolyRegion(kid, "ellipse-region"); reg->setRegionInfo(info); } cerr << "Number of texture regions is " << len << endl; } /** * Name: parseColor * * Purpose: get all the color attributes into the Image object */ void parseColor(Image *i, DOMDocument *doc, DOMElement *root) { double width = strtod(XMLString::transcode(root->getAttribute(XMLString::transcode("image-width"))), NULL); double height = strtod(XMLString::transcode(root->getAttribute(XMLString::transcode("image-height"))), NULL ); double scale = strtod(XMLString::transcode(root->getAttribute(XMLString::transcode("scale"))), NULL); Color_regions *regs = new Color_regions(width, height, scale); i->setColorRegions(regs); DOMNodeList *children = root->getElementsByTagName(XMLString::transcode("color-polygon-region")); XMLSize_t len = children->getLength(); for(XMLSize_t j = 0;jitem(j)); DOMNodeList *color = kid->getElementsByTagName(XMLString::transcode("color-mean")); double r = strtod(XMLString::transcode((color->item(0))->getTextContent()), NULL); double g = strtod(XMLString::transcode((color->item(1))->getTextContent()), NULL); double b = strtod(XMLString::transcode((color->item(2))->getTextContent()), NULL); Color_region *reg = new Color_region(r, g, b); DOMNodeList *covariance = kid->getElementsByTagName(XMLString::transcode("color-covariance")); if(covariance->getLength() != 9) cerr << "The number of color covariance regions isn't 9" << endl; double *covs = new double[9]; for(XMLSize_t d = 0; dgetLength();d++) { covs[d] = strtod(XMLString::transcode((covariance->item(d))->getTextContent()), NULL); } Color_covariance *cov = new Color_covariance(covs, covariance->getLength()); reg->setColorCovariance(cov); Region_info *info = parsePolyRegion(kid, "ellipse-region"); reg->setRegionInfo(info); } cerr << "Number of color regions is " << len << endl; } /** * Name: hex_to_color * * Purpose: Convert hex colors to RGB and return a Color object * * Notes: this function is used for the structure regions, where color is encoded in hex */ Color *hex_to_color(char *color) { char *r_s1 = new char[5]; r_s1[0] = '0'; r_s1[1] = 'x'; r_s1[2] = color[2]; r_s1[3] = color[3]; r_s1[4] = '\0'; double red_1 = strtod(r_s1, NULL); char *g_s1 = new char[5]; g_s1[0] = '0'; g_s1[1] = 'x'; g_s1[2] = color[4]; g_s1[3] = color[5]; g_s1[4] = '\0'; double green_1 = strtod(g_s1, NULL); char *b_s1 = new char[5]; b_s1[0] = '0'; b_s1[1] = 'x'; b_s1[2] = color[6]; b_s1[3] = color[7]; b_s1[4] = '\0'; double blue_1 = strtod(b_s1, NULL); return new Color(red_1, green_1, blue_1); } /** * Name: parseStructure * * Purpose: get all the structure attributes into the Image object */ void parseStructure(Image *i, DOMDocument *doc, DOMElement *root) { Line_clusters *regs; DOMNodeList *clusters = root->getElementsByTagName(XMLString::transcode("line-cluster")); XMLSize_t len = clusters->getLength(); double img_width, img_height; // getting all the structure attributes into the image datastructure // possibility for multiple line clusters for each image for(XMLSize_t j = 0;jitem(j)); double total_len = strtod(XMLString::transcode(kid->getAttribute(XMLString::transcode("total-len"))), NULL); if(j==0) { // the width and height attributes will be the same in each cluster for a particular image, so we only // need to extract that once and associate it will all the clusters img_width = strtod(XMLString::transcode(kid->getAttribute(XMLString::transcode("image-width"))), NULL); img_height = strtod(XMLString::transcode(kid->getAttribute(XMLString::transcode("image-height"))), NULL); regs = new Line_clusters(img_width, img_height, 1); i->setLineRegions(regs); } Line_cluster *cluster = new Line_cluster(total_len, img_width, img_height); DOMNodeList *colors = kid->getElementsByTagName(XMLString::transcode("color-pair")); if(colors->getLength() != 0) { DOMElement *color_pair = (DOMElement *)(colors->item(0)); int color1 = atoi(XMLString::transcode(color_pair->getAttribute(XMLString::transcode("color1")))); int color2 = atoi(XMLString::transcode(color_pair->getAttribute(XMLString::transcode("color2")))); char col_1[8]; sprintf(col_1, "%x", color1); Color *color_1_final = hex_to_color(col_1); char col_2[8]; sprintf(col_2, "%x", color2); Color *color_2_final = hex_to_color(col_2); cluster->setColors(color_1_final, color_2_final); } DOMNodeList *base = kid->getElementsByTagName(XMLString::transcode("base-pair")); if(base->getLength() != 0) { DOMElement *base_pair = (DOMElement *) (base->item(0)); int id = atoi(XMLString::transcode(base_pair->getAttribute(XMLString::transcode("id")))); if(id != 0) cerr << "ERR: The id of a baseline wasn't 0!" << endl; double x1 = strtod(XMLString::transcode(base_pair->getAttribute(XMLString::transcode("x1"))), NULL); double y1 = strtod(XMLString::transcode(base_pair->getAttribute(XMLString::transcode("y1"))), NULL); double x2 = strtod(XMLString::transcode(base_pair->getAttribute(XMLString::transcode("x2"))), NULL); double y2 = strtod(XMLString::transcode(base_pair->getAttribute(XMLString::transcode("y2"))), NULL); cluster->setBaseLine(new Line(new Point(x1, y1), new Point(x2, y2), id)); } DOMNodeList *convergence = kid->getElementsByTagName(XMLString::transcode("converging-point")); if(convergence->getLength() != 0) { DOMElement *conv_pt = (DOMElement *) (convergence->item(0)); double x1 = strtod(XMLString::transcode(conv_pt->getAttribute(XMLString::transcode("col"))), NULL); double y1 = strtod(XMLString::transcode(conv_pt->getAttribute(XMLString::transcode("row"))), NULL); cluster->setConvergePoint(new Point(x1, y1)); } Region_info *info = parsePolyRegion(kid, "ellipse-region"); cluster->setRegionInfo(info); DOMNodeList *lines = kid->getElementsByTagName(XMLString::transcode("line")); for(XMLSize_t m=0;mgetLength();m++) { DOMElement *line = (DOMElement *) (lines->item(m)); double x1 = strtod(XMLString::transcode(line->getAttribute(XMLString::transcode("x1"))), NULL); double y1 = strtod(XMLString::transcode(line->getAttribute(XMLString::transcode("y1"))), NULL); double x2 = strtod(XMLString::transcode(line->getAttribute(XMLString::transcode("x2"))), NULL); double y2 = strtod(XMLString::transcode(line->getAttribute(XMLString::transcode("y2"))), NULL); int id = atoi(XMLString::transcode(line->getAttribute(XMLString::transcode("id")))); cluster->addLine(new Line(new Point(x1, y1), new Point(x2, y2), id)); } // changing the coordinate system such that (0, 0) is in the lower lefthand corner, rather than the center // this is only necessary for the structure files int moveX = (int)(round(img_width/2)); int moveY = (int)(round(img_height/2)); cluster->recenterLines(moveX, moveY); regs->addRegion(*cluster); } } /** * Name: makeHistogram * * Purpose: divides the line segments of a cluster into |divisions| buckets according * to orientation and stores that information in an array of Histogram elements */ Histogram_element *makeHistogram(Line_cluster *cluster, int divisions) { double start = 0; double stop = 0; double step = (double)180/(double)divisions; Histogram_element *h = new Histogram_element[divisions]; vector *lines; int total_lines = cluster->getNumLines(); for(int n=0;ngetLinesContained(start, stop); h[n] = *(new Histogram_element(start, stop, lines, total_lines)); } return h; } /** * Name: write_html_file * * Purpose: writes an html file for the data from the structure regions * the file has the name of the Image concatenated with "_structure_data.html" */ void write_html_file (char *fileName, int numOfClusters, int image_size, Html_cluster **clusters) { string origFileName(fileName); string newFileName = origFileName + "_structure_data.html"; string structFileName = origFileName + ".CLC_LineStruct.bound.gif"; ofstream outFile(newFileName.c_str()); outFile << "" < Original Structure " << endl; outFile << " " << endl; outFile << " " << endl; if(CLASSIFYING && KMEANS) { outFile << "" << endl; outFile << "
Clusters
" << endl; } outFile << "

Original File Name: " << origFileName << endl; outFile << "

Number Of Clusters: " << numOfClusters << endl; outFile << "

Image Size: " << image_size << endl; outFile << "

Cluster Info: " << endl; for (int i = 0; i < numOfClusters; i++) { outFile << "" << endl; outFile << "

Cluster " << i+1 << ": " << endl; //outFile << "

" <" << numOfClusters << "" <getArea(); double density; density = clusters[i]->getNumLines()/area; double relArea; relArea = clusters[i]->getArea()/image_size; outFile << "" << endl; outFile << "" <" << clusters[i]->getNumLines() << "" < " << endl; outFile << "" << endl; outFile << "" << endl; outFile << "" <" << area << "" <" << endl; outFile << "" << endl; outFile << "" <" << density << "" <" << endl; double len_per_area = clusters[i]->getTotalLength()/area; outFile << "" << endl; outFile << "" <" << len_per_area << "" <" << endl; outFile << "" << endl; outFile << "" <" << relArea << "" <" << endl; outFile << "" << endl; double max_len = clusters[i]->getMaxLength(); outFile << "" <" << max_len << "" <" << endl; outFile << "" << endl; double min_len = clusters[i]->getMinLength(); outFile << "" <" << min_len << "" <" << endl; outFile << "
Number Of Clusters
Number Of Lines
Area
Density (number lines / area)
Density (length lines / area)
Relative Area
Max Length Line
Min Length Line
"; outFile << "

" << endl; int num_hist_divs = clusters[i]->getNumHistogram(); Histogram_element *h = clusters[i]->getHistogram(); outFile << "" << endl; outFile << "" << endl; for (int j = 0; j < num_hist_divs ; j++) { outFile << "" << endl; } outFile << "" << endl << ""; for (int j = 0; j < num_hist_divs ; j++) { outFile << "" << endl; outFile << "" << endl; } outFile << "" << endl << "
Probability " << h[j].getProbability() << endl; outFile << "
Range Start Angle: " << h[j].getStartAngle() << " End Angle: " << h[j].getStopAngle() << "
" << endl; outFile << "

" << endl; } outFile << ""<< endl; outFile.close(); } /** * Name: write_structure_classes * * Purpose: writes to a text file that is used to classify each cluster region * * Notes: * * When in CLASSIFY mode: * * for sal ruiz's classifiers, the output file is in the format: * class_number(GROUP) feature_number_1:value_1 feature_number_2:value_2 ... * is now outputting in a sparse format, i.e., if value_n = 0, nothing is printed * (ex-- feature_n-1:value_n-1 feature_n+1:value_n+1) * * When in KMEANS mode: * * the output file is in the format: * N K vector_1 vector_2 vector_3 ... vector_m * where each vector_i is of length N, N is the number of features that are being used to classify * each cluster, and K is the number of classes that I want the clusters divided into */ int write_structure_classes(Image *i, ofstream *outFile) { cerr << "got into write structure classes" << endl; Line_clusters *lines = (i->getLineRegions()); Line_cluster line_cluster = lines->getFirst(); int image_size = (int)(line_cluster.getWidth() * line_cluster.getHeight()); int num_clusters = i->getNumHtmlClusters(); Html_cluster **clusters = i->getHmtlClusters(); int total_num_features = 0; for(int j=0;jgetArea(); double len_per_area = clusters[j]->getTotalLength()/area; double density = clusters[j]->getNumLines()/area; double relArea = clusters[j]->getArea()/image_size; double **matrix = clusters[j]->getMatrix(); int cluster_rows = (clusters[j]->getRows()); int cluster_cols = (clusters[j]->getCols()); // sets the total number of features based on the length-angle histogram and the features listed above if((FIRST_TIME_THRU_STRUCT_CLASSES) && (j==0) && (KMEANS)) { total_num_features = 3 + (cluster_rows+1) * (cluster_cols+1); cerr << "total num features is " << total_num_features << endl; *outFile << total_num_features << endl; *outFile << GROUP << endl; FIRST_TIME_THRU_STRUCT_CLASSES = false; } if(KMEANS) { int index=0; for(int r=0;r<=cluster_rows;r++) { for(int c=0;c<=cluster_cols;c++, index++) { *outFile << " " << matrix[r][c]; } } cluster_rows++; *outFile << " " << len_per_area; cluster_rows++; *outFile << " " << density; cluster_rows++; *outFile << " " << relArea; *outFile << endl; } else { *outFile << GROUP; int index=0; for(int r=0;r<=cluster_rows;r++) { for(int c=0;c<=cluster_cols;c++, index++) { if(matrix[r][c]) { *outFile << " " << index << ":" << matrix[r][c]; } } } cluster_rows++; *outFile << " " << index << ":" << len_per_area; cluster_rows++; *outFile << " " << ++index << ":" << density; cluster_rows++; *outFile << " " << ++index << ":" << relArea; *outFile << endl; } } return total_num_features; } /** * Name: write_length_angle_gif * * Purpose: creates a length-angle histogram for each line cluster, writing it to a gif file * * Notes: creates a ppm file initially, to represent the length-angle histogram for each * cluster converts that to a gif file and deletes the ppm file that was written * currently, the maxval is set at 255 for each RGB element, but that could be changed */ void write_length_angle_gif(Image *i) { string origName(i->getName()); int num_clusters = i->getNumHtmlClusters(); Html_cluster** clusters = i->getHmtlClusters(); for(int n=0;ngetCols() + 1) << " " << (current->getRows() + 1) << endl; double maxval = 255; outFile << maxval << endl; double **matrix = current->getMatrix(); for(int r=0;r<=current->getRows();r++) { for(int c=0; c<=current->getCols();c++) { // must output the value 3 times because the PPM format is expecting RGB values for(int rgb=0;rgb<3;rgb++) { outFile << (maxval - (int)(matrix[r][c] * maxval)) << " "; } outFile << " "; } outFile << endl; } string command = "ppmtogif "; string fullCommand = command + fileNamePPM + " > " + fileNameGIF; system(fullCommand.c_str()); string removePPM = "rm " + fileNamePPM; system(removePPM.c_str()); } } /** * Name: processStructure * * Purpose: writes the html and histograms for the Images that had a structure XML file */ void processStructure(Image *i) { char *fileName = i->getName(); Line_clusters *lines = i->getLineRegions(); int num_clusters = lines->getNumClusters(); int image_size; Html_cluster **clusters = new Html_cluster*[num_clusters]; // cerr << "number of clusters is " << num_clusters << endl; for(int j=0;jgetFirst(); image_size = (int)(cluster.getWidth() * cluster.getHeight()); } else { cluster = lines->getNext(); } int num_lines = cluster.getNumLines(); double area = cluster.getArea(); Html_cluster *htm = new Html_cluster(num_lines, area, NUM_DIVISIONS_ANGLE); double length = cluster.getTotalLength(); htm->setTotalLength(length); Histogram_element *h = makeHistogram(&cluster, NUM_DIVISIONS_ANGLE); // rows are angles, cols are lengths Matrix *matrix = new Matrix(h, NUM_DIVISIONS_ANGLE, NUM_DIVISIONS_LENGTH, MATRIX_LENGTH_LIMIT); htm->setMatrix(matrix); htm->setHistogram(h); Line *max = cluster.getMaxLengthLine(); Line *min = cluster.getMinLengthLine(); htm->setMaxLength(max->getLength()); htm->setMinLength(min->getLength()); clusters[j] = htm; } write_html_file(fileName, num_clusters, image_size, clusters); i->setNumHtmlClusters(num_clusters); i->setHtmlClusters(clusters); write_length_angle_gif(i); } /** * Name: endsInXML * * Purpose: ensures that the string passed in ends in ".xml" */ bool endsInXML(char *name) { int len = strlen(name); if ((name[--len] != 'l') || (name[--len] != 'm') || (name[--len] != 'x') || (name[--len] != '.')) { return false; } else { return true; } } /** * Name: draw_lines * * Purpose: To draw the lines of each cluster onto the canvas of ints--if a point about to be written overlaps with another * labelled point, then the new label will be placed to both the immediate right and left of the original point * */ void draw_lines(int rows, int cols, int **canvas, Line_cluster cluster) { int label = cluster.getLabel(); int num_lines = cluster.getNumLines(); Line *current; for(int j=0;jgetPoint1(); Point *p2 = current->getPoint2(); int startX, startY, endX, endY; if(p1->getX() < p2->getX()) { startX = (int)(p1->getX()); startY = (int)(p1->getY()); endX = (int)(p2->getX()); endY = (int)(p2->getY()); } else { startX = (int)(p2->getX()); startY = (int)(p2->getY()); endX = (int)(p1->getX()); endY = (int)(p1->getY()); } // cerr << "start x is " << startX << " startY is " << startY << " endX is " << endX << " endY is " << endY << endl; double slope = (double)(endY - startY) / (double)(endX - startX); int b = endY - (int) (slope * endX); // cerr << "slope is " << slope << " and b is " << b << endl; // NOTE: IF there are missing lines or portions of lines, check here and change it to Y-dependent int currY; for(int currX =startX; currX<=endX;currX++) { currY = (int) (slope * currX) + b; if(((currX+1) > cols) || (currY > rows)) { cerr << "PROBLEM: draw_lines, out of bounds on canvas" << endl; cerr << "x is " << currX << " and cols is " << cols << endl; } /* cerr << "x is " << currX << " and rows is " << rows << endl; cerr << "y is " << currY << " and cols is " << cols << endl; */ if((!canvas[currY][currX]) || (canvas[currY][currX] == label)){ canvas[currY][currX] = label; } else { canvas[currY][currX-1] = label; canvas[currY][currX+1] = label; } } } } void fill_lines(int rows, int cols, int **canvas) { int last_label = 0; int current_label; cerr << "getting into fill lines" << endl; for(int r=0;rgetLineRegions(); cols = (int) lines->getWidth(); // X coords rows = (int) lines->getHeight(); // Y coords cerr << "cols (width) is " << cols << " and rows (height) is " << rows << endl; canvas = new int *[rows]; for(int r=0;rgetNumClusters();k++) { Line_cluster cluster; if(k==0) { cluster = lines->getFirst(); } else { cluster = lines->getNext(); } draw_lines(rows, cols, canvas, cluster); } } else if(TYPE==COLOR) { } else if(TYPE==TEXTURE) { } fill_lines(rows, cols, canvas); } /** * Name: kmeans_classify * * Purpose: use Viet's k-means function to classify the images that have been processed */ void kmeans_classify() { int num_buckets = GROUP; //****SHOULD ADD OUTPUT FILE NAME AS ONE OF THE PARAMETERS string syscall = PATH_TO_KMEANS + " " + KMEANS_FILENAME; system(syscall.c_str()); string fileName = KMEANS_FILENAME + KMEANS_EXTENSION; ifstream *inFile = new ifstream(fileName.c_str()); int label = 0; vector::iterator iter = ls->begin(); cerr << "KMEANS_CLASSIFY: before the checks on type" << endl; cerr << "type is " << TYPE << " and structure is " << STRUCTURE << endl; if(TYPE == STRUCTURE) { cerr << "kmeans_classify: type was structure" << endl; for(unsigned int n=0;nsize();n++) { Line_clusters *lines = (*iter)->getLineRegions(); int num_clusters = lines->getNumClusters(); for(int m=0;m> label_str; label = atoi(label_str.c_str()); Line_cluster cluster; if(m==0) { cluster = lines->getFirst(); } else { cluster = lines->getNext(); } cluster.setLabel(label); } draw_clusters_gif(*iter); iter++; } } else if(TYPE == TEXTURE) { } else if(TYPE == COLOR) { } } /** * main */ int main(int argc, char *argv[]) { cerr << "Got into main" << endl; try { XMLPlatformUtils::Initialize(); } catch (const XMLException& toCatch) { char* message = XMLString::transcode(toCatch.getMessage()); cerr << "Error during initialization! :\n" << message << "\n"; XMLString::release(&message); return 1; } XercesDOMParser* parser = new XercesDOMParser(); parser->setValidationScheme(XercesDOMParser::Val_Always); // optional. parser->setDoNamespaces(true); // optional ErrorHandler* errHandler = (ErrorHandler*) new HandlerBase(); parser->setErrorHandler(errHandler); char *classify = "classify"; char *kMeans = "kmeans"; ofstream *outFile; if (argc == 1) { cerr << USAGE_FULL; return -1; } else if(((!strcmp(classify, argv[1])) || (!strcmp(kMeans, argv[1]))) && (argc > 2)) { GROUP = atoi(argv[2]); BEFORE_FILES_START = 3; CLASSIFYING = 1; string fileName; if(!strcmp(kMeans, argv[1])) { // doesn't make sense to try to have 0 or fewer groups when using k-means if(GROUP <= 0) { cerr << "ERROR: Number of groups is " << GROUP << endl; cerr << USAGE << USAGE_KMEANS; return -1; } KMEANS = true; char num_k[8]; sprintf(num_k, "%d", GROUP); string num_k_str(num_k); fileName = "kMeans_" + num_k_str + ".txt"; outFile = new ofstream(fileName.c_str()); } else { char group_char[8]; sprintf(group_char, "%d", GROUP); string group(group_char); fileName = "class_" + group + ".txt"; outFile = new ofstream(fileName.c_str()); } KMEANS_FILENAME = fileName; cerr << "named the outfile " << fileName << " for classification" << endl; } else if (!(endsInXML(argv[1]))) { cerr << USAGE_FULL; return -1; } else { BEFORE_FILES_START = 1; CLASSIFYING = 0; GROUP = -1; cerr << "argc is " << argc << endl; cerr << "first arg of that is " << argv[1] << endl; } for(int n=BEFORE_FILES_START; nparse(xmlFile); } catch (const XMLException& toCatch) { char* message = XMLString::transcode(toCatch.getMessage()); cerr << "Exception message is: \n" << message << "\n"; XMLString::release(&message); return -1; } catch (const DOMException& toCatch) { char* message = XMLString::transcode(toCatch.msg); cerr << "Exception message is: \n" << message << "\n"; XMLString::release(&message); return -1; } catch (const exception& e) { cerr << "Unexpected Exception \n" ; return -1; } // the file was parsed, and now a document exists DOMDocument *doc = parser->getDocument(); DOMElement *root = doc->getDocumentElement(); XMLCh const *tag = root->getTagName(); // the name of the root should be one of the following strings XMLCh const *color = XMLString::transcode("color-polygon-regions"); XMLCh const *texture = XMLString::transcode("texture-polygon-regions"); XMLCh const *structure = XMLString::transcode("line-clusters"); int col_result = XMLString::compareIString(color, tag); int text_result = XMLString::compareIString(texture, tag); int struct_result = XMLString::compareIString(structure, tag); char *fileName; Image *i; if(!col_result || !text_result) { const char *suffix = ".s256"; char*fileNameExtension = strstr(xmlFile, suffix); int len = fileNameExtension - xmlFile; fileName = new char[len + 1]; strncpy(fileName, xmlFile, len); fileName[len] = '\0'; if(!col_result) { cerr << "color file for image " << fileName << endl; i = new Image(fileName); ls->push_back(i); parseColor(i, doc, root); cerr << "done with parsing the color" << endl; } else { cerr << "texture file for image " << fileName << endl; i = new Image(fileName); ls->push_back(i); parseTexture(i, doc, root); cerr << "done with parsing the texture" << endl; } } else if(!struct_result) { const char *suffix = ".CLC_"; char*fileNameExtension = strstr(xmlFile, suffix); int len = fileNameExtension - xmlFile; fileName = new char[len + 1]; strncpy(fileName, xmlFile, len); fileName[len] = '\0'; cerr << "filename after '\0' is " << fileName << endl; cerr << "was structure file " << fileName << endl; i = new Image(fileName); cerr << "filename after image is " << i->getName() << endl; ls->push_back(i); parseStructure(i, doc, root); // cerr << "done with parsing the structure" << endl; // cerr << "about to process structure " << endl; processStructure(i); if(n==BEFORE_FILES_START) { NUM_FEATURES_KMEANS = write_structure_classes(i, outFile); cerr << "about to set the damn type to be structure" << endl; TYPE = "structure"; //string(STRUCTURE); } else { write_structure_classes(i, outFile); } } else { cerr << "ERROR: was an undefined file file" << endl; return -1; } } if(CLASSIFYING) { cerr << "going to try to write structure classes" << endl; outFile->close(); if(KMEANS) { cerr << "calling kmeans_classify" << endl; kmeans_classify(); } } cerr << "size of list is " << ls->size() << endl; int size = ls->size(); vector::iterator iter = ls->begin(); for(int m=0;mhasStructure()) { cerr << "name is " << (*iter)->getName() << endl; // cerr << (*iter)->getName() << " has structure" << endl; //} iter++; } delete parser; delete errHandler; return 0; }