#include #include #include "vectorization.h" void drawPixel(int x, int y, RGB& color, unsigned char* mask, int width, int height) { int index = (y*width + x)*3; mask[index ] = color.b; mask[index+1] = color.g; mask[index+2] = color.r; } void drawPoint(int x, int y, RGB& color, unsigned char* mask, int width, int height) { drawPixel(x, y, color, mask, width, height); if(x>0) drawPixel(x-1, y, color, mask, width, height); if(x0) drawPixel(x, y-1, color, mask, width, height); if(y= abs(dy)) { if(dx<0) { iaux=x0; x0=x1; x1=iaux; iaux=y0; y0=y1; y1=iaux; } for(i=x0; i<=x1; i++) { if(dx==0) j = y0; else j = y0 + ((i-x0)*(y1-y0))/abs(dx); iaux = (j*width + i)*3; mask[iaux ] = segColor.b; mask[iaux+1] = segColor.g; mask[iaux+2] = segColor.r; } } else { if(dy<0) { iaux=x0; x0=x1; x1=iaux; iaux=y0; y0=y1; y1=iaux; } for(j=y0; j<=y1; j++) { if(dy==0) i = x0; else i = x0 + ((j-y0)*(x1-x0))/abs(dy); iaux = (j*width + i)*3; mask[iaux ] = segColor.b; mask[iaux+1] = segColor.g; mask[iaux+2] = segColor.r; } } drawPoint(x0, y0, vertColor, mask, width, height); drawPoint(x1, y1, vertColor, mask, width, height); } void drawCycle(pointSet& cycle, RGB& vertColor, RGB& segColor, unsigned char* mask, int width, int height) { int i, size; RGB firstColor; firstColor.r = 255; firstColor.g = 255; firstColor.b = 0; RGB secondColor; secondColor.r = 0; secondColor.g = 255; secondColor.b = 0; size = cycle.size(); if(size < 3) return; for(i=0; i<(size-1); i++) { drawPoint(cycle[i].x, cycle[i].y, vertColor, mask, width, height); drawLine(cycle[i].x, cycle[i].y, cycle[i+1].x, cycle[i+1].y, vertColor, segColor, mask, width, height); } drawPoint(cycle[size-1].x, cycle[size-1].y, vertColor, mask, width, height); drawLine(cycle[size-1].x, cycle[size-1].y, cycle[0].x, cycle[0].y, vertColor, segColor, mask, width, height); drawPoint(cycle[0].x, cycle[0].y, firstColor, mask, width, height); drawPoint(cycle[1].x, cycle[1].y, secondColor, mask, width, height); } void drawObjects(objectSet& objects, unsigned char* img, int width, int height) { int i; RGB vertColor; RGB segColor; RGB starColor; vertColor.r = 255; vertColor.g = 0; vertColor.b = 0; segColor.r = 0; segColor.g = 255; segColor.b = 0; starColor.r = 255; starColor.g = 128; starColor.b = 0; for(i=0; i=0) { if(i==-1) nextDirection = up_left; if(i==0) nextDirection = up; if(i==1) nextDirection = up_right; return true; } break; case down: if(j<=0) { if(i==-1) nextDirection = down_left; if(i==0) nextDirection = down; if(i==1) nextDirection = down_right; return true; } break; case left: if(i<=0) { if(j==-1) nextDirection = down_left; if(j==0) nextDirection = left; if(j==1) nextDirection = up_left; return true; } break; case right: if(i>=0) { if(j==-1) nextDirection = down_right; if(j==0) nextDirection = right; if(j==1) nextDirection = up_right; return true; } break; case up_left: nextDirection = up_left; if(((j==1)&&((i==0)||(i==-1)))||((j==0)&&(i==-1))) return true; break; case up_right: nextDirection = up_right; if(((j==1)&&((i==0)||(i==1)))||((j==0)&&(i==1))) return true; break; case down_left: nextDirection = down_left; if(((j==-1)&&((i==0)||(i==-1)))||((j==0)&&(i==-1))) return true; break; case down_right: nextDirection = down_right; if(((j==-1)&&((i==0)||(i==1)))||((j==0)&&(i==1))) return true; break; } return false; } bool isQuad(object& obj) { int i, n, step; double perimeterMarks[3] = {0.37, 0.62, 0.87}; double angleMarks[3] = {90, 180, 270}; double perimeter = 0; double angTotal = 0; double x0, y0, x1, y1, x2, y2, ang; double angTol = 45; double direction = 1; step = 0; n = obj.points.size(); for(i=0; i= perimeterMarks[step]) { if((step==0)&&(ang<0)) direction = -1; if(fabs(angTotal - direction*angleMarks[step]) > angTol) return false; step++; } } obj.name = "Quadrilatero"; if(direction == -1) obj.clockWise = false; else obj.clockWise = true; return true; } void nVertices(object& obj, int numVertices) { int i, j, n, maxIndex; double x0, y0, x1, y1, x2, y2, ang, maxAng; vector angs; vector isVertice; vector vertices; n = obj.points.size(); if(numVertices >= n) return; for(i=0; i maxAng)) { maxAng = angs[j]; maxIndex = j; } } if(maxIndex >= 0) { isVertice[maxIndex] = true; } } for(i=0; i angVec; double perimeter = 0; double area = 0; int i, x0, y0, x1, y1, dx, dy, xmin, xmax, ymin, ymax, iaux, size; iaux = 0; size = obj.points.size(); if(size < 3) return false; xmin = obj.points[0].x; xmax = obj.points[0].x; ymin = obj.points[0].y; ymax = obj.points[0].y; for(i=0; ixmax) xmax = x0; if(x0ymax) ymax = y0; if(y0= width)||(new_pt.y < 0)||(new_pt.y >= height)) continue; nextIndex = index+i*3+j*width*3; nextValue = mask[nextIndex]; isInDirection = checkDirection(direction, i, j, nextDirection); dx = (new_pt.x)-(origin.x); dy = (new_pt.y)-(origin.y); dist = sqrt(dx*dx + dy*dy); if(nextValue == 0) continue; // nextNumBlacks = num_blacks; // if(nextValue == 0) nextNumBlacks++; // if(nextNumBlacks > dist / 20) continue; if((nextValue == 2)&&(dist > 3.00)) { cycleCandidates.push_back(new_pt); } if(isInDirection) { if(dx==0) ang = 3.1416 / 2.00; else ang = atan((double)dy / (double)dx); if(nextDirection == up) ang = 3.1416 / 2.0; if(nextDirection == down) ang = -3.1416 / 2.0; if(nextDirection == left) ang = 3.1416; if(nextDirection == right) ang = 0.0; if(nextDirection == up_left) ang += 3.1416; if(nextDirection == down_left) { if(direction == left) { ang_min -= 2.0*3.1416; ang_max -= 2.0*3.1416; } ang -= 3.1416; } if((angang_max)) isInDirection = false; } if(!isInDirection) { if(nextValue == 255) { nextCandidates.push_back(new_pt); } } else { if(dist>line_width_tol) { alfa = asin(line_width_tol / dist); ang1 = ang + alfa; ang2 = ang - alfa; } else { ang1=ang_max; ang2=ang_min; } if(ang1>ang_max) ang1=ang_max; if(ang2 guardianTable; void findCycles2(point pt, unsigned char* mask, objectSet& objects, int width, int height) { guardianTable verticeTable; pointSet allCandidates; pointSet nextCandidates; pointSet cycleCandidates; object cycle; point currPoint; guardianPoint currEntry; int i, j, k, common_pt_index, index; currEntry.location = pt; currEntry.previousVertices.clear(); verticeTable.push_back(currEntry); while(verticeTable.size() > 0) { currEntry = verticeTable[verticeTable.size()-1]; verticeTable.pop_back(); currPoint = currEntry.location; nextCandidates.clear(); allCandidates.clear(); cycleCandidates.clear(); traceLines2(currPoint, currPoint, any, -2.0*3.1416, 2.0*3.1416, -1, allCandidates, cycleCandidates, mask, width, height); for(i=0; i0) { nextCandidates.push_back(allCandidates[i]); } } currEntry.previousVertices.push_back(currPoint); for(i=0; icommon_pt_index; k--) { cycle.points.push_back(verticeTable[j].previousVertices[k]); } if(validateObject(cycle)) { // drawCycle(cycle.points, img_out, width, height); objects.push_back(cycle); return; } } } } for(i=0; i 0) mask[index] = 2; currEntry.location = nextCandidates[i]; verticeTable.push_back(currEntry); } } } void vectorizeMask2(unsigned char* img_in, unsigned char* img_aux, objectSet& objects, int width, int height) { int i, j, index; point pt; for(i=0; i=width-2)||(j>=height-2)) { img_aux[index ] = 0; img_aux[index+1] = 0; img_aux[index+2] = 0; continue; } img_aux[index ] = img_in[index ]; img_aux[index+1] = img_in[index+1]; img_aux[index+2] = img_in[index+2]; } for(i=0; i vector shiftVector(vector& vec, int d) { vector result; int size = vec.size(); for(int i=0; i=0)&&(x=0)&&(y