void radial_sample(int width, int height, char* data, IplImage *unwrapped, int slice) { IplImage *cvcast = cvCreateImageHeader(cvSize(width, height), IPL_DEPTH_8U, 1); cvcast->imageData = data; // cvSaveImage("slice.png",cvcast); CvPoint center = cvPoint(cx,cy); unsigned char* linebuf; for(int sample = 0; sample < RADIAL_SAMPLES; sample++) { float theta = ((float)sample)*((2.0*PI)/(float)RADIAL_SAMPLES); CvPoint outer = calc_ray_outer(theta, center); // printf("%g:\t%d,%d\n", theta*(180.0/PI), outer.x, outer.y); cvClipLine(cvSize(width, height), &outer, ¢er); int linesize = abs(center.x-outer.x)+abs(center.y-outer.y)+1; linebuf = (unsigned char*)malloc(linesize); cvSampleLine(cvcast,outer,center,linebuf,4); IplImage *castline = cvCreateImageHeader(cvSize(linesize,1), IPL_DEPTH_8U, 1); castline->imageData = (char*)linebuf; IplImage *sobel = cvCreateImage(cvSize(linesize,1), IPL_DEPTH_8U, 1); cvSobel(castline, sobel, 1, 0, 3); int layer = 0; for(int i = 0; (i < linesize) && (layer < MAX_LAYERS); i++) { // printf(" %d,", (int)cvGetReal1D(sobel,i)); if((int)cvGetReal1D(sobel,i) > SOBEL_THRESH) { int max = 0, max_i = 0; for(; i < linesize; i++) { int curval = (int)cvGetReal1D(sobel,i); if(curval == 0) break; if(curval > max) { max = curval; max_i = i; } } cvSetReal2D(unwrapped,slice,(layer*RADIAL_SAMPLES)+sample,cvGetReal1D(castline,max_i)); // printf("%d\t",max); layer++; } } // printf("\n"); /* char filename[] = "line000.png"; sprintf(filename,"line%03d.png",(int)(theta*(180.0/PI))); cvSaveImage(filename,sobel); */ cvReleaseImageHeader(&castline); cvReleaseImage(&sobel); free(linebuf); } }
static CvStatus icvPreWarpImage8uC3R( int numLines, /* number of scanlines */ uchar * src, /* source image */ int src_step, /* line step */ uchar * dst, /* dest buffers */ int *dst_nums, /* lens of buffer */ CvSize src_size, /* image size in pixels */ int *scanlines ) /* scanlines array */ { int k; CvPoint start; CvPoint end; int curr; int curr_dst; CvMat mat; curr = 0; curr_dst = 0; cvInitMatHeader( &mat, src_size.height, src_size.width, CV_8UC3, src, src_step ); for( k = 0; k < numLines; k++ ) { start.x = scanlines[curr++]; start.y = scanlines[curr++]; end.x = scanlines[curr++]; end.y = scanlines[curr++]; #ifdef _DEBUG { CvLineIterator iterator; assert( cvInitLineIterator( &mat, start, end, &iterator, 8 ) == dst_nums[k] ); } #endif cvSampleLine( &mat, start, end, dst + curr_dst, 8 ); curr_dst += dst_nums[k] * 3; } return CV_NO_ERR; }
void find_box(const IplImage *blocks, CvPoint offset, int zoom, int dir16, CvPoint *best_left, CvPoint *best_right, int *best_quality, IplImage *debug) { float a = (float) dir16 / 8.0 * CV_PI; int size = blocks->height / 2; float spacing = fabs(cos(a)) > fabs(sin(a)) ? fabs(cos(a)) : fabs(sin(a)); int lines = (int) round((float) size / spacing); float line_x = (float) size * cos(a) / 2.0; float line_y = (float) size * sin(a) / 2.0; // printf("dir16=%d spacing=%.3f size=%d line_x=%.3f line_y=%.3f\n", // dir16, spacing, size, line_x, line_y); // Scanline data int length = 2 * size + 1; uchar buffer[3 * length]; // Results from scanlines int lefts[lines]; int rights[lines]; int qualities[lines]; // Process each scanline for (int y = 0; y < lines; y++) { lefts[y] == 0; rights[y] == 0; qualities[y] == 0; float up = spacing * (float) (y - lines / 2); CvPoint pt1 = cvPoint((int) round((float) size - sin(a) * up - line_x), (int) round((float) size + cos(a) * up - line_y)); CvPoint pt2 = cvPoint((int) round((float) size - sin(a) * up + line_x), (int) round((float) size + cos(a) * up + line_y)); // if (y < 3 || y >= lines - 3) // printf(" y=%d pt1=%d,%d pt2=%d,%d\n", y, pt1.x, pt1.y, pt2.x, pt2.y); /* Draw all scan lines in blue if (debug) cvLine(debug, cvPoint(pt1.x * zoom, pt1.y * zoom), cvPoint(pt2.x * zoom, pt2.y * zoom), CV_RGB(0, 0, 255), 1, 8, 0); */ if (pt1.x < 0 || pt1.x >= blocks->width) continue; if (pt1.y < 0 || pt1.y >= blocks->height) continue; if (pt2.x < 0 || pt2.x >= blocks->width) continue; if (pt2.y < 0 || pt2.y >= blocks->height) continue; int count = cvSampleLine(blocks, pt1, pt2, buffer, 8); find_line_range(dir16, count, buffer, &lefts[y], &rights[y], &qualities[y]); if (!qualities[y]) continue; if (rights[y] - lefts[y] + 1 < MIN_WIDTH) continue; float c = (float) (count - 1); CvPoint l = interpolate(pt1, pt2, (float) lefts[y] / c, offset, zoom); CvPoint r = interpolate(pt1, pt2, (float) rights[y] / c, offset, zoom); if (debug) cvLine(debug, l, r, cvScalar(0, 0, 255, 255), 1, 8, 0); } *best_quality = 0; int best_middle = 0; int best_l = 0; int best_r = 0; int best_count = 0; int first = 0; int last = -1; while (last < lines) { first = last + 1; while (first < lines && !qualities[first]) first++; last = first; int quality = 0; while (last < lines && qualities[last]) { if (rights[last + 1] < lefts[last]) break; if (lefts[last + 1] > rights[last]) break; quality += qualities[last]; last++; } int count = last - first; int middle = (first + last) / 2; if (count < MIN_LINES) continue; last--; if (quality > *best_quality) { *best_quality = quality; best_count = count; best_middle = middle; qsort(&lefts[first], count, sizeof(int), compare_int); best_l = lefts[middle] - 3; qsort(&rights[first], count, sizeof(int), compare_int); best_r = rights[middle] + 3; } } float up = spacing * (float) (best_middle - lines / 2); CvPoint pt1 = cvPoint((int) round((float) size - sin(a) * up - line_x), (int) round((float) size + cos(a) * up - line_y)); CvPoint pt2 = cvPoint((int) round((float) size - sin(a) * up + line_x), (int) round((float) size + cos(a) * up + line_y)); int count = cvSampleLine(blocks, pt1, pt2, buffer, 8); float c = (float) (count - 1); *best_left = interpolate(pt1, pt2, (float) best_l / c, offset, zoom); *best_right = interpolate(pt1, pt2, (float) best_r / c, offset, zoom); if (debug) cvLine(debug, *best_left, *best_right, cvScalar(0, 0, 255, 255), 3, 8, 0); }
int cveSampleLine(const void* _img, CvPoint* pt1, CvPoint* pt2, void* _buffer, int connectivity) { return cvSampleLine(_img, *pt1, *pt2, _buffer, connectivity); }