/* 寻找能合并成长线段的线段集合
 * lineSegments 所有线段的数组
 * lineSetArray lineSegments数组
 * <return>线段集合构成的数组</return>
 */
LineSetArray* groupLineSegments(SegmentsArray* lineSegments, LineSetArray* lineSetArray)
{
	/*****寻找能合并成长线段的线段集合*****/
	for(int i=0; i<lineSegments->count; i++)
	{
		if(lineSegments->flag[i] == 0)
		{
			int k=0; //k为当前正在处理的tempLineSet中线段的索引
			SegmentsArray tempLineSet = {5, 0, (CvPoint2D32f(*)[2])malloc(5*sizeof(CvPoint2D32f[2])), (char*)malloc(5*sizeof(char))};
			tempLineSet.pointArray[tempLineSet.count][0] = lineSegments->pointArray[i][0];
			tempLineSet.pointArray[tempLineSet.count][1] = lineSegments->pointArray[i][1];
			(tempLineSet.count)++;
			lineSegments->flag[i] = 1;
			while(k<tempLineSet.count) //如果tempLineSet中还有未处理的线段
			{
				for(int j=i+1; j<lineSegments->count; j++)
				{
					if(lineSegments->flag[j] == 0)
					{
						if(mergeLineJudge(&(tempLineSet.pointArray[k][0]), &(tempLineSet.pointArray[k][1]), &(lineSegments->pointArray[j][0]), &(lineSegments->pointArray[j][1]), (float)(M_PI/ANGLE_THRESHOLD), (float)DISTANCE_THRESHOLD))
						{
							/*****如果tempLineSet内存不够,则将数组长度+5*****/
							if(tempLineSet.count >= tempLineSet.length)
							{
								tempLineSet.length += 5;
								CvPoint2D32f (*tempPointArray)[2];
								char* tempFlag;
								tempPointArray = (CvPoint2D32f(*)[2])malloc(sizeof(CvPoint2D32f[2]) * tempLineSet.length);
								tempFlag = (char*)malloc(sizeof(char) * tempLineSet.length);
								for(int m=0; m<tempLineSet.count; m++)
								{
									tempPointArray[m][0] = tempLineSet.pointArray[m][0];
									tempPointArray[m][1] = tempLineSet.pointArray[m][1];
									tempFlag[m] = tempLineSet.flag[m];
								}
								free(tempLineSet.pointArray);
								free(tempLineSet.flag);
								tempLineSet.pointArray = tempPointArray;
								tempLineSet.flag = tempFlag;
							}

							tempLineSet.pointArray[tempLineSet.count][0] = lineSegments->pointArray[j][0];
							tempLineSet.pointArray[tempLineSet.count][1] = lineSegments->pointArray[j][1];
							(tempLineSet.count)++;
							lineSegments->flag[j] = 1;
						}
					}
				}
				k++;
			}
			lineSetArray->lineSet[lineSetArray->count] = tempLineSet;
			(lineSetArray->count)++;
			/*****如果lineSetArray内存不够,则将数组长度+10*****/
			if(lineSetArray->count >= lineSetArray->length)
			{
				lineSetArray->length += 10;
				SegmentsArray* tempSegmentsArray = (SegmentsArray*)malloc(lineSetArray->length * sizeof(SegmentsArray));
				for(int m=0; m<lineSetArray->count; m++)
				{
					tempSegmentsArray[m] = lineSetArray->lineSet[m];
				}
				free(lineSetArray->lineSet);
				lineSetArray->lineSet = tempSegmentsArray;
			}
		}
	}
	return lineSetArray;
}
Example #2
0
    void draw()
    {
        double scale = this->scale == 0? 1.0 : this->scale;
        CvScalar colors[5] = {
#if !defined CV_VERSION_EPOCH && (CV_VERSION_MAJOR >= 3)
            CvScalar(cvRound(color[0].r * 255), cvRound(color[0].g * 255), cvRound(color[0].b * 255), cvRound(alpha * 255)),
            CvScalar(cvRound(color[1].r * 255), cvRound(color[1].g * 255), cvRound(color[1].b * 255), cvRound(alpha * 255)),
            CvScalar(cvRound(color[2].r * 255), cvRound(color[2].g * 255), cvRound(color[2].b * 255), cvRound(alpha * 255)),
            CvScalar(cvRound(color[3].r * 255), cvRound(color[3].g * 255), cvRound(color[3].b * 255), cvRound(alpha * 255)),
            CvScalar(cvRound(color[4].r * 255), cvRound(color[4].g * 255), cvRound(color[4].b * 255), cvRound(alpha * 255)),
#else
            {{cvRound(color[0].r * 255), cvRound(color[0].g * 255), cvRound(color[0].b * 255), cvRound(alpha * 255)}},
            {{cvRound(color[1].r * 255), cvRound(color[1].g * 255), cvRound(color[1].b * 255), cvRound(alpha * 255)}},
            {{cvRound(color[2].r * 255), cvRound(color[2].g * 255), cvRound(color[2].b * 255), cvRound(alpha * 255)}},
            {{cvRound(color[3].r * 255), cvRound(color[3].g * 255), cvRound(color[3].b * 255), cvRound(alpha * 255)}},
            {{cvRound(color[4].r * 255), cvRound(color[4].g * 255), cvRound(color[4].b * 255), cvRound(alpha * 255)}},
#endif
        };
        
        for (int i = 0; i < (objects ? objects->total : 0); i++)
        {
            CvRect* r = (CvRect*) cvGetSeqElem(objects, i);
            CvPoint center;
            int thickness = stroke <= 0? CV_FILLED : cvRound(stroke * 100);
            int linetype = antialias? CV_AA : 8;
            
            center.x = cvRound((r->x + r->width * 0.5) / scale);
            center.y = cvRound((r->y + r->height * 0.5) / scale);
            
            switch (shape == 1.0? (rand() % 3) : cvRound(shape * 10))
            {
            default:
            case 0:
                {
                    int radius = cvRound((r->width + r->height) * 0.25 / scale);
                    cvCircle(image, center, radius, colors[i % 5], thickness, linetype);
                    break;
                }
            case 1:
                {
#if !defined CV_VERSION_EPOCH && (CV_VERSION_MAJOR >= 3)
                    CvBox2D box = CvBox2D(CvPoint2D32f(center.x, center.y), CvSize2D32f(r->width / scale, (r->height / scale) * 1.2), 90);
#else
                    CvBox2D box = {{center.x, center.y}, {r->width / scale, (r->height / scale) * 1.2}, 90};
#endif
                    cvEllipseBox(image, box, colors[i % 5], thickness, linetype);
                    break;
                }
            case 2:
                {
#if !defined CV_VERSION_EPOCH && (CV_VERSION_MAJOR >= 3)
                    CvPoint pt1 = CvPoint(r->x / scale, r->y / scale);
                    CvPoint pt2 = CvPoint((r->x + r->width) / scale, (r->y + r->height) / scale);
#else
                    CvPoint pt1 = {r->x / scale, r->y / scale};
                    CvPoint pt2 = {(r->x + r->width) / scale, (r->y + r->height) / scale};
#endif
                    cvRectangle(image, pt1, pt2, colors[i % 5], thickness, linetype);
                    break;
                }
            }
        }
    }
/* 将矢量化结果中的拐角线从拐点处断开,并先合并平行相连的线段
 * potrace_state 矢量化输出结果
 * lineSegments 拐角点断开并合并后的线段数组
 */
void breakCornerAndRecombine(potrace_state_t* potrace_state, SegmentsArray* lineSegments)
{
	int i;
	potrace_path_t* pNext = potrace_state->plist;
	while(pNext != NULL)
	{
		potrace_curve_t* curve = &(pNext->curve);
		/*****为lineSegments增加curve->n的数组长度*****/
		lineSegments->length = lineSegments->count+2*curve->n;
		CvPoint2D32f (*tempPointArray)[2];
		char* tempFlag;
		tempPointArray = (CvPoint2D32f(*)[2])malloc(sizeof(CvPoint2D32f[2]) * lineSegments->length);
		tempFlag = (char*)malloc(sizeof(char) * lineSegments->length);
		for(int m=0; m<lineSegments->count; m++)
		{
			tempPointArray[m][0] = lineSegments->pointArray[m][0];
			tempPointArray[m][1] = lineSegments->pointArray[m][1];
			tempFlag[m] = lineSegments->flag[m];
		}
		free(lineSegments->pointArray);
		free(lineSegments->flag);
		lineSegments->pointArray = tempPointArray;
		lineSegments->flag = tempFlag;

		for(i=0; i<curve->n; i++) //遍历闭合曲线中的每个片段
		{
			if(curve->tag[i] == POTRACE_CORNER) //如果是拐角线片段
			{
				lineSegments->flag[lineSegments->count] = 0;
				//每次循环存储的是当前拐角线的第二个直线片段和下一个拐角线的第一个直线片段
				lineSegments->pointArray[lineSegments->count][0].x = (float)curve->c[i][1].x;
				lineSegments->pointArray[lineSegments->count][0].y = (float)curve->c[i][1].y;
				lineSegments->pointArray[lineSegments->count][1].x = (float)curve->c[i][2].x;
				lineSegments->pointArray[lineSegments->count][1].y = (float)curve->c[i][2].y;
				(lineSegments->count)++;

				lineSegments->flag[lineSegments->count] = 0;
				lineSegments->pointArray[lineSegments->count][0].x = (float)curve->c[i][2].x;
				lineSegments->pointArray[lineSegments->count][0].y = (float)curve->c[i][2].y;
				if(i == curve->n-1) //最后一个曲线片段的下一个拐角线是第一个拐角线
				{
					lineSegments->pointArray[lineSegments->count][1].x = (float)curve->c[0][1].x;
					lineSegments->pointArray[lineSegments->count][1].y = (float)curve->c[0][1].y;
				}
				else
				{
					lineSegments->pointArray[lineSegments->count][1].x = (float)curve->c[i+1][1].x;
					lineSegments->pointArray[lineSegments->count][1].y = (float)curve->c[i+1][1].y;
				}
				(lineSegments->count)++;

				//判断该次循环存储的两个直线片段是否能构成一条长直线
				if(mergeLineJudge(&(lineSegments->pointArray[lineSegments->count-2][0]), &(lineSegments->pointArray[lineSegments->count-2][1]), &(lineSegments->pointArray[lineSegments->count-1][0]), &(lineSegments->pointArray[lineSegments->count-1][1]), (float)(M_PI/ANGLE_THRESHOLD), (float)DISTANCE_THRESHOLD))
				{
					CvPoint2D32f* temp = mergeLine(&(lineSegments->pointArray[lineSegments->count-2][0]), &(lineSegments->pointArray[lineSegments->count-2][1]), &(lineSegments->pointArray[lineSegments->count-1][0]), &(lineSegments->pointArray[lineSegments->count-1][1]));
					lineSegments->pointArray[lineSegments->count-2][0] = temp[0];
					lineSegments->pointArray[lineSegments->count-2][1] = temp[1];
					lineSegments->flag[lineSegments->count-1] = 1;
				}
			}
		}
		pNext = pNext->next;
	}
}