void RegionGrow<ImageSigT>::grow( Matrix<PixelType>& image ) { //复制图像,大于0的值全部赋255 int rows = image.rows(); int cols = image.cols(); Matrix<unsigned char> img_copy = image.transform<unsigned char>(); for( int i=0; i<rows; ++i ) for( int j=0; j<cols; ++j ) { if( img_copy(i,j)>0 ) img_copy(i,j) = 255; } //在复制图像上做区域增长。不可以并行 for( int i=0; i<rows; ++i ) for( int j=0; j<cols; ++j ) { if( img_copy(i,j) !=0 ) { m_region_counter++; getBlock( i, j, img_copy ); } } //在要输出的区域大小序列里,把面积阈值以下的删掉 for(std::vector<int>::iterator iter=m_pixel_num_vector.begin(); iter!=m_pixel_num_vector.end(); ) { if( *iter <= m_min_area) iter = m_pixel_num_vector.erase(iter); else iter ++ ; } }
int pgm_overlay(AVPicture *dst, const AVPicture *s1, int s1height, int s1row, int s1col, const AVPicture *s2, int s2height) { const int dstwidth = dst->linesize[0]; const int s1width = s1->linesize[0]; const int s2width = s2->linesize[0]; int rr; if (dstwidth != s1width) { VERBOSE(VB_COMMFLAG, QString("pgm_overlay want width %1, have %2") .arg(s1width).arg(dst->linesize[0])); return -1; } img_copy(dst, s1, PIX_FMT_GRAY8, s1width, s1height); /* Overwrite overlay area of "dst" with "s2". */ for (rr = 0; rr < s2height; rr++) memcpy(dst->data[0] + (s1row + rr) * s1width + s1col, s2->data[0] + rr * s2width, s2width); return 0; }
void UndistortImages(const std::vector<image_t> &images, const fisheye_params_t &fisheye_params) { int num_images = (int) images.size(); for (int i = 0; i < num_images; i++) { img_t *img = LoadJPEG(images[i].name.c_str()); img_t *img_u; if (images[i].is_fisheye) { printf("Undistorting image %s\n", images[i].name.c_str()); img_u = UndistortImage(img, fisheye_params); } else { printf("Skipping image %s (not marked as fisheye).\n", images[i].name.c_str()); img_u = img_copy(img); } const std::string out = images[i].name.substr(0, images[i].name.length() - 3).append("fd.jpg"); WriteJPEG(img_u, (const char *) out.c_str()); img_free(img); img_free(img_u); } }
static int write(struct img_pixmap *img, struct img_io *io) { struct img_pixmap fimg; img_init(&fimg); if(img_copy(&fimg, img) == -1) { img_destroy(&fimg); return -1; } if(img_convert(&fimg, IMG_FMT_RGBF) == -1) { img_destroy(&fimg); return -1; } if(rgbe_write_header(io, fimg.width, fimg.height, 0) == -1) { img_destroy(&fimg); return -1; } if(rgbe_write_pixels_rle(io, fimg.pixels, fimg.width, fimg.height) == -1) { img_destroy(&fimg); return -1; } img_destroy(&fimg); return 0; }
int img_convert(struct img_pixmap *img, enum img_fmt tofmt) { struct pixel pbuf[8]; int bufsz = (img->width & 7) == 0 ? 8 : ((img->width & 3) == 0 ? 4 : 1); int i, num_pix = img->width * img->height; int num_iter = num_pix / bufsz; char *sptr, *dptr; struct img_pixmap nimg; if(img->fmt == tofmt) { return 0; /* nothing to do */ } img_init(&nimg); if(img_set_pixels(&nimg, img->width, img->height, tofmt, 0) == -1) { img_destroy(&nimg); return -1; } sptr = img->pixels; dptr = nimg.pixels; for(i=0; i<num_iter; i++) { unpack[img->fmt](pbuf, sptr, bufsz); pack[tofmt](dptr, pbuf, bufsz); sptr += bufsz * img->pixelsz; dptr += bufsz * nimg.pixelsz; } img_copy(img, &nimg); img_destroy(&nimg); return 0; }
static int write(struct img_pixmap *img, struct img_io *io) { int i, nlines = 0; struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; struct dst_mgr dest; struct img_pixmap tmpimg; unsigned char **scanlines; img_init(&tmpimg); if(img->fmt != IMG_FMT_RGB24) { if(img_copy(&tmpimg, img) == -1) { return -1; } if(img_convert(&tmpimg, IMG_FMT_RGB24) == -1) { img_destroy(&tmpimg); return -1; } img = &tmpimg; } if(!(scanlines = malloc(img->height * sizeof *scanlines))) { img_destroy(&tmpimg); return -1; } scanlines[0] = img->pixels; for(i=1; i<img->height; i++) { scanlines[i] = scanlines[i - 1] + img->width * img->pixelsz; } cinfo.err = jpeg_std_error(&jerr); /* XXX */ jpeg_create_compress(&cinfo); dest.pub.init_destination = init_destination; dest.pub.empty_output_buffer = empty_output_buffer; dest.pub.term_destination = term_destination; dest.io = io; cinfo.dest = (struct jpeg_destination_mgr*)&dest; cinfo.image_width = img->width; cinfo.image_height = img->height; cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults(&cinfo); jpeg_start_compress(&cinfo, 1); while(nlines < img->height) { int res = jpeg_write_scanlines(&cinfo, scanlines + nlines, img->height - nlines); nlines += res; } jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); free(scanlines); img_destroy(&tmpimg); return 0; }
void demo_monitor(void) { static uint16_t cnt = TIMEOUT; if (--cnt) return; cnt = TIMEOUT; { img_xor(0xFF, image); img_copy(0, image); } }
static void mainLoop(void) { ARUint8 *dataPtr; ARMarkerInfo *marker_info; int marker_num; int areamax; int i; if( (dataPtr = (unsigned char *)arVideoGetImage()) == NULL ) { arUtilSleep(2); return; } img_copy( dataPtr, image, xsize*ysize*AR_PIX_SIZE ); arVideoCapNext(); if( arDetectMarker(image, thresh, &marker_info, &marker_num) < 0 ) { cleanup(); exit(0); } areamax = 0; target = NULL; for( i = 0; i < marker_num; i++ ) { if( marker_info[i].area > areamax ) { areamax = marker_info[i].area; target = &(marker_info[i]); } } argDispImage( image, 0, 0 ); if( target != NULL ) { glLineWidth( 2.0 ); glColor3d( 0.0, 1.0, 0.0 ); argLineSeg( target->vertex[0][0], target->vertex[0][1], target->vertex[1][0], target->vertex[1][1], 0, 0 ); argLineSeg( target->vertex[3][0], target->vertex[3][1], target->vertex[0][0], target->vertex[0][1], 0, 0 ); glColor3d( 1.0, 0.0, 0.0 ); argLineSeg( target->vertex[1][0], target->vertex[1][1], target->vertex[2][0], target->vertex[2][1], 0, 0 ); argLineSeg( target->vertex[2][0], target->vertex[2][1], target->vertex[3][0], target->vertex[3][1], 0, 0 ); } argSwapBuffers(); return; }
void process() { /* static int tmc=0; tmc++; if(tmc==30) { tmc=0; set_indoor(); } */ int x, y; //初始化背景 if(bInited==0) { static int initCount=0; if(initCount<30) { initCount++; img_copy(&BACK, &Y); } else { bInited=1; img_fill(&UBAK, 0); set_target_pan_tilt(0, 0); set_zoom(1); } return; } img_fill(&COMP, 0); img_fill(&COMPB, 0); img_fill(&CLUS, 0); img_fill(&LABEL, 0); //计算准备 for (y = masky1; y < masky2; y++) for (x = maskx1; x < maskx2; x++) { COMP.data[y][x] = abs(Y.data[y][x] - PREV.data[y][x]) > compare_th ? 255 : 0; if(Y.data[y][x] < dark || PREV.data[y][x] < dark) COMP.data[y][x] = abs(Y.data[y][x] - PREV.data[y][x]) > compare_th*dark_th ? 255 : 0; COMPB.data[y][x] = abs(Y.data[y][x] - BACK.data[y][x]) > compare_th2 ? 255 : 0; if(Y.data[y][x] < dark || BACK.data[y][x] < dark) COMPB.data[y][x] = abs(Y.data[y][x] - BACK.data[y][x]) > compare_th2*dark_th ? 255 : 0; } img_copy(&PREV, &Y); //选择性更新背景 updataBack(); //聚类 cluster(); img_copy(&LABEL, &CLUS); //连通域 int k=label(); img_plot_rect(&Y, maskx1, masky1, maskx2 - maskx1, masky2 - masky1, 128); //输出连通域信息 int i=0; mon("count: %d\n", k); for(i=0;i<k;i++) { mon("area%d: %d\n", i, Box[i].area); } float p=0,t=0,z=1; int ml=IMG_W,mr=0,cx=0,dx; for(i=0;i<k;i++) { if(Box[i].left < ml) ml = Box[i].left; if(Box[i].right > mr) mr = Box[i].right; } cx=(ml+mr)/2; dx=(mr-ml)*1.3; p = (float)(cx - IMG_W/2) / (IMG_W/2) * (PAN_RANGE/2); z = CAM_RANGE / ((float)dx / IMG_W * PAN_RANGE); if(z<1.0) z=1; printf("--------%d\n",k); myTimer(&p,&t,&z,k); set_target_pan_tilt(p, t); set_zoom(z); mon("PZ:%f,%f\n", p, z); }
bool CC(std::vector<CCStats> &ccstats, const ImageGray<BYTE> &imgbi, ImageRGB<BYTE> &imgFeedback) { ImageGray<BYTE> img_copy(imgbi); std::vector<Pixel> firstPixels; double meansize = 0; for (int i = 0; i < imgbi.xsize(); i++) { for (int j = 0; j < imgbi.ysize(); j++) { std::vector<Pixel> ccC; CCStats stats; int npix = extract_cc_(Pixel(i, j), ccC, img_copy); if (npix > 180) { extract_CCStats(ccC, stats, imgbi); double compactness = 4*PI*stats.nPoints / (stats.perimeter*stats.perimeter); // !!compactness < 1.3 is not a good limit! I changed to 1.5 -Leman if (std::min(stats.radius1, stats.radius2) > 8 && compactness < 1.5 && compactness > 0.7) { ccstats.push_back(stats); firstPixels.push_back(Pixel(i, j)); meansize += stats.nPoints; // draw Feedback for (int k = 0; k < ccC.size(); ++k) { Pixel p = ccC[k]; // black means detected imgFeedback.pixel_R(p.x, p.y) = 0; imgFeedback.pixel_G(p.x, p.y) = 0; imgFeedback.pixel_B(p.x, p.y) = 0; } } else { // draw Feedback for (int k = 0; k < ccC.size(); ++k) { Pixel p = ccC[k]; // red means it's not a circle imgFeedback.pixel_R(p.x, p.y) = 150; imgFeedback.pixel_G(p.x, p.y) = 0; imgFeedback.pixel_B(p.x, p.y) = 0; } } } else { // draw Feedback for (int k = 0; k < ccC.size(); ++k) { Pixel p = ccC[k]; // green means it's too small imgFeedback.pixel_R(p.x, p.y) = 0; imgFeedback.pixel_G(p.x, p.y) = 150; imgFeedback.pixel_B(p.x, p.y) = 0; } } } double percent = ((double)i / (double)imgbi.xsize())*100; if (!(i % (int)(0.2*imgbi.xsize()+1))) libMsg::cout<<(int)(percent+1)<<'%'<<libMsg::flush; else if (!(i % (int)(0.04*imgbi.xsize()+1))) libMsg::cout<<'.'<<libMsg::flush; } libMsg::cout<<libMsg::endl; if (ccstats.size() == 0) { libMsg::cout<<"Nothing interesting found in this image. Please check."; return false; } // retrieve min_size and max_size to build a size histogram int max_val = 0; int rad_thre = 7; for (int i = 0; i < ccstats.size(); i++) { if (ccstats[i].nPoints > max_val) max_val = ccstats[i].nPoints; } std::vector<int> hist(max_val); std::vector<std::stack<int> > hist_stack(max_val); // to keep indeces of all the circles for given size // run through all the sizes and build frequency histogram for (int i = 0; i < ccstats.size(); i++) { int val = ccstats[i].nPoints-1; hist[val]++; hist_stack[val].push(i); } meansize /= ccstats.size(); int commonsize = meansize; libMsg::cout<<"Average area of region: "<<meansize<<" pixels"<<libMsg::endl; libMsg::cout<<"Max area of region: "<<max_val<<" pixels"<<libMsg::endl; libMsg::cout<<"Region found before filter: [ "<<ccstats.size()<<" ]"<<libMsg::endl; /* * frequency * ^ * | * | * | | * | | | larger than zerogap * | | | so we ignore A and B * | <---> | ||||| | | <---------------> * | A | | ||||| || | | B * ----------------------------------------------------> size * 0 ^ 10000 * | * average size * negative <---- ----> positive * direction direction */ // collect the inliers in positive direction from commonsize idx int zerosgap = meansize/5; int count = 0; int flag = zerosgap; std::vector<int> inliers(ccstats.size()); while (flag != 0 && commonsize+count < hist.size()) { int hist_idx = commonsize + count; int onesizecircles = hist[hist_idx]; if (onesizecircles == 0) { flag--; } else { while (!hist_stack[hist_idx].empty()) { inliers[hist_stack[hist_idx].top()] = 1; // inliers.push(hist_stack[hist_idx].top()); hist_stack[hist_idx].pop(); } flag = zerosgap; } count++; } // collect the inliers in negative direction from commonsize idx count = -1; flag = zerosgap; while (flag != 0 && commonsize+count >= 0) { int hist_idx = commonsize + count; int onesizecircles = hist[hist_idx]; if (onesizecircles == 0) { flag--; } else { while (!hist_stack[hist_idx].empty()) { inliers[hist_stack[hist_idx].top()] = 1; hist_stack[hist_idx].pop(); } flag = zerosgap; } count--; } std::vector<CCStats> erasedCCStats; std::vector<int> outliersIdx; int idx = 0; while (idx < ccstats.size()) { if (inliers[idx] == 0) { erasedCCStats.push_back(ccstats[idx]); outliersIdx.push_back(idx); ccstats.erase(ccstats.begin() + idx); inliers.erase(inliers.begin() + idx); } else { idx++; } } libMsg::cout<<"Region found after filter: [ "<<ccstats.size()<<" ]"<<libMsg::endl; if (erasedCCStats.size() > 0) { libMsg::cout<<"Erased circles:"<<libMsg::endl; ImageGray<BYTE> img_copy2(imgbi); for (int i = 0; i < erasedCCStats.size(); ++i) { CCStats &stats = erasedCCStats[i]; libMsg::cout<<"circle "<<i<<libMsg::endl; libMsg::cout<<"\tarea: "<<stats.nPoints<<libMsg::endl; libMsg::cout<<"\tcenter: "<<stats.centerX<<", "<<stats.centerY<<libMsg::endl; int index = outliersIdx[i]; Pixel first = firstPixels[index]; std::vector<Pixel> ccC; extract_cc_(first, ccC, img_copy2); for (int k = 0; k < ccC.size(); ++k) { Pixel p = ccC[k]; // blue means filtered imgFeedback.pixel_R(p.x, p.y) = 0; imgFeedback.pixel_G(p.x, p.y) = 0; imgFeedback.pixel_B(p.x, p.y) = 150; } } } return true; }
/** * \brief copy frame data from buffer to AVFrame, handling stride. * \param f destination AVFrame * \param src source buffer, does not use any line-stride * \param width width of the video frame * \param height height of the video frame */ static void copy_frame(AVFrame *f, uint8_t *src, int width, int height) { AVPicture pic; avpicture_fill(&pic, src, PIX_FMT_YUV420P, width, height); img_copy((AVPicture *)f, &pic, PIX_FMT_YUV420P, width, height); }
int pgm_convolve_radial(AVPicture *dst, AVPicture *s1, AVPicture *s2, const AVPicture *src, int srcheight, const double *mask, int mask_radius) { /* * Pad and convolve an image. * * "s1" and "s2" are caller-pre-allocated "scratch space" (avoid repeated * per-frame allocation/deallocation). * * Remove noise from image; smooth by convolving with a Gaussian mask. See * http://www.cogs.susx.ac.uk/users/davidy/teachvision/vision0.html * * Optimization for radially-symmetric masks: implement a single * two-dimensional convolution with two commutative single-dimensional * convolutions. */ const int srcwidth = src->linesize[0]; const int newwidth = srcwidth + 2 * mask_radius; const int newheight = srcheight + 2 * mask_radius; int ii, rr, cc, rr2, cc2; double sum; /* Get a padded copy of the src image for use by the convolutions. */ if (pgm_expand_uniform(s1, src, srcheight, mask_radius)) return -1; /* copy s1 to s2 and dst */ img_copy(s2, s1, PIX_FMT_GRAY8, newwidth, newheight); img_copy(dst, s1, PIX_FMT_GRAY8, newwidth, newheight); /* "s1" convolve with column vector => "s2" */ rr2 = mask_radius + srcheight; cc2 = mask_radius + srcwidth; for (rr = mask_radius; rr < rr2; rr++) { for (cc = mask_radius; cc < cc2; cc++) { sum = 0; for (ii = -mask_radius; ii <= mask_radius; ii++) { sum += mask[ii + mask_radius] * s1->data[0][(rr + ii) * newwidth + cc]; } s2->data[0][rr * newwidth + cc] = (unsigned char)(sum + 0.5); } } /* "s2" convolve with row vector => "dst" */ for (rr = mask_radius; rr < rr2; rr++) { for (cc = mask_radius; cc < cc2; cc++) { sum = 0; for (ii = -mask_radius; ii <= mask_radius; ii++) { sum += mask[ii + mask_radius] * s2->data[0][rr * newwidth + cc + ii]; } dst->data[0][rr * newwidth + cc] = (unsigned char)(sum + 0.5); } } return 0; }
avframe::avframe() : tobefreed(0),w(0),h(0),dw(0),pix_fmt(),img_convert_ctx(0) #else avframe::avframe() : tobefreed(0),w(0),h(0),dw(0),pix_fmt() #endif { f=avcodec_alloc_frame(); } avframe::avframe(AVFrame *src, AVCodecContext *ctx) : f(0),tobefreed(0) { f=avcodec_alloc_frame(); tobefreed=malloc(avpicture_get_size(ctx->pix_fmt, ctx->width, ctx->height)); avpicture_fill((AVPicture *)f, (u_int8_t*)tobefreed, ctx->pix_fmt,ctx->width,ctx->height); #if LIBAVCODEC_VERSION_INT >= (51 << 16) av_picture_copy((AVPicture *)f, (const AVPicture *) src, ctx->pix_fmt, ctx->width, ctx->height); #else img_copy((AVPicture *)f, (const AVPicture *) src, ctx->pix_fmt, ctx->width, ctx->height); #endif f->pict_type = src->pict_type; f->quality = src->quality; f->coded_picture_number = src->coded_picture_number; f->display_picture_number = src->display_picture_number; f->pts = src->pts; f->interlaced_frame = src->interlaced_frame; f->top_field_first = src->top_field_first; f->repeat_pict = src->repeat_pict; f->quality = src->quality; w=ctx->width; h=ctx->height; pix_fmt=ctx->pix_fmt; dw=w*ctx->sample_aspect_ratio.num/ctx->sample_aspect_ratio.den; #ifdef HAVE_LIB_SWSCALE img_convert_ctx=sws_getContext(w, h, pix_fmt, w, h, PIX_FMT_BGR24, SWS_BICUBIC, NULL, NULL, NULL); #endif } avframe::~avframe() { if (tobefreed) free(tobefreed); if (f) av_free(f); #ifdef HAVE_LIB_SWSCALE if (img_convert_ctx) sws_freeContext(img_convert_ctx); #endif } QImage avframe::getqimage(bool scaled, double viewscalefactor) { #ifdef HAVE_LIB_SWSCALE if (w<=0 || h<=0 || img_convert_ctx==NULL) #else if (w<=0 || h<=0) #endif return QImage(); uint8_t *rgbbuffer=(uint8_t*)malloc(avpicture_get_size(PIX_FMT_RGB24, w, h)+64); int headerlen=sprintf((char *) rgbbuffer, "P6\n%d %d\n255\n", w, h); AVFrame *avframergb=avcodec_alloc_frame(); avpicture_fill((AVPicture*)avframergb, rgbbuffer+headerlen, PIX_FMT_RGB24,w,h); #ifdef HAVE_LIB_SWSCALE sws_scale(img_convert_ctx, f->data, f->linesize, 0, h, avframergb->data, avframergb->linesize); #else img_convert((AVPicture *)avframergb, PIX_FMT_RGB24, (AVPicture*)f, pix_fmt, w, h); #endif QImage im; im.loadFromData(rgbbuffer, headerlen+w*h*3, "PPM"); #ifdef HAVE_LIB_SWSCALE // im = im.swapRGB(); im = im.rgbSwapped(); #endif if ((scaled && w!=dw)||(viewscalefactor!=1.0)) { #ifdef SMOOTHSCALE im = im.smoothScale(int((scaled?dw:w)/viewscalefactor+0.5), int(h/viewscalefactor+0.5)); #else // im = im.scale(int((scaled?dw:w)/viewscalefactor+0.5), int(h/viewscalefactor+0.5)); im = im.scaled(int((scaled?dw:w)/viewscalefactor+0.5), int(h/viewscalefactor+0.5)); #endif } free(rgbbuffer); av_free(avframergb); return (im); }
static int write_file(struct img_pixmap *img, struct img_io *io) { png_struct *png; png_info *info; png_text txt; struct img_pixmap tmpimg; unsigned char **rows; unsigned char *pixptr; int i, coltype; img_init(&tmpimg); if(!(png = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0))) { return -1; } if(!(info = png_create_info_struct(png))) { png_destroy_write_struct(&png, 0); return -1; } /* if the input image is floating-point, we need to convert it to integer */ if(img_is_float(img)) { if(img_copy(&tmpimg, img) == -1) { return -1; } if(img_to_integer(&tmpimg) == -1) { img_destroy(&tmpimg); return -1; } img = &tmpimg; } txt.compression = PNG_TEXT_COMPRESSION_NONE; txt.key = "Software"; txt.text = "libimago2"; txt.text_length = 0; if(setjmp(png_jmpbuf(png))) { png_destroy_write_struct(&png, &info); img_destroy(&tmpimg); return -1; } png_set_write_fn(png, io, write_func, flush_func); coltype = fmt_to_png_type(img->fmt); png_set_IHDR(png, info, img->width, img->height, 8, coltype, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_set_text(png, info, &txt, 1); if(!(rows = malloc(img->height * sizeof *rows))) { png_destroy_write_struct(&png, &info); img_destroy(&tmpimg); return -1; } pixptr = img->pixels; for(i=0; i<img->height; i++) { rows[i] = pixptr; pixptr += img->width * img->pixelsz; } png_set_rows(png, info, rows); png_write_png(png, info, 0, 0); png_write_end(png, info); png_destroy_write_struct(&png, &info); free(rows); img_destroy(&tmpimg); return 0; }
void demo_init(void) { img_set(0xFF, image); img_copy(0, image); }