void ComputeFrequencyProperty(Image *img, ACCProperty *ppt) { ulong x, y, p, q; uchar d, r; AdjRel *A; Pixel v; int i; for (p=0; p<img->nrows*img->ncols; p++) for (d=0; d<4; d++) ppt[p].frequency[d] = 0; A = Circular(1.0); for(y=0; y<img->nrows; y++) for(x=0; x<img->ncols; x++){ p = x + img->tbrow[y]; for(r=1,d=0; r<=7; r+=2,d++) for (i=1; i < A->n; i++){ v.x = x + r * A->dx[i]; v.y = y + r * A->dy[i]; if (ValidPixel(img,v.x,v.y)){ q = v.x + img->tbrow[v.y]; if(ppt[p].color == ppt[q].color) ppt[p].frequency[d]++; } } } DestroyAdjRel(&A); }
void ComputeFrequencyProperty(Image *img, Property *ppt) { long x, y, p, q; int i, border; AdjRel *A; Pixel v; A = Circular(1.0); for(y=0; y<img->nrows; y++){ for(x=0; x<img->ncols; x++){ p = x + img->tbrow[y]; border=false; for (i=1; i < A->n; i++){ v.x = x + A->dx[i]; v.y = y + A->dy[i]; if (ValidPixel(img,v.x,v.y)){ q = v.x + img->tbrow[v.y]; if(ppt[p].color!=ppt[q].color){ border=true; break; } } } if(border==false) ppt[p].frequency=LOW; else ppt[p].frequency=HIGH; } } DestroyAdjRel(&A); }
CImage *DrawLabeledRegions(Image *img, Image *label){ CImage *border=CreateCImage(img->ncols,img->nrows); int x,y,k,p,q,u,v; AdjRel *A; A = Circular(1.0); for(y=0;y<img->nrows;y++){ for(x=0;x<img->ncols;x++){ p = x + img->tbrow[y]; border->C[0]->val[p]= border->C[1]->val[p]=border->C[2]->val[p]=img->val[p]; for(k=1;k<A->n;k++){ u = x+A->dx[k]; v = y+A->dy[k]; if(ValidPixel(img,u,v)){ q= u + img->tbrow[v]; if (label->val[p] != label->val[q]){ border->C[0]->val[p]=255; border->C[1]->val[p]=0; border->C[2]->val[p]=0; break; } } } } } DestroyAdjRel(&A); return(border); }
CImage *DrawCBorder(Image *img, Image *label){ CImage *border; int i,j,k,p,q,u,v; AdjRel *A; Image *img8; img8 = ConvertToNbits(img, 8); border = Convert2CImage(img8); DestroyImage(&img8); A = Circular(1.0); for(i=0;i<img->nrows;i++){ for(j=0;j<img->ncols;j++){ p = j + img->tbrow[i]; for(k=1;k<A->n;k++){ u = j+A->dx[k]; v = i+A->dy[k]; if(ValidPixel(img,u,v)){ q= u + img->tbrow[v]; if (label->val[p] < label->val[q]){ switch( label->val[q]){ case 0: border->C[0]->val[p] = 255; border->C[1]->val[p] = 255; border->C[2]->val[p] = 255; break; case 1: border->C[0]->val[p] = 255; border->C[1]->val[p] = 0; border->C[2]->val[p] = 0; break; case 2: border->C[0]->val[p] = 0; border->C[1]->val[p] = 255; border->C[2]->val[p] = 0; break; case 3: border->C[0]->val[p] = 0; border->C[1]->val[p] = 0; border->C[2]->val[p] = 255; break; default: border->C[0]->val[p] = 255; border->C[1]->val[p] = 255; border->C[2]->val[p] = 0; } break; } } } } } DestroyAdjRel(&A); return border; }
Firework(const Vec2& pos, int count) : m_particles(count) { for (auto& particle : m_particles) { const Vec2 v = Circular(Random(10.0, 80.0), Random(TwoPi)); particle.pos = pos + v; particle.v0 = v * 2.0; } }
void LinearFilter::CircularIndexingConvolution() { Mat src = original_image_; Mat dst = processed_image_; float sum, x1, y1; for (int y = 0; y < src.rows; y++) { for (int x = 0; x < src.cols; x++) { sum = 0.0; for (int k = -radius_ / 2; k <= radius_ / 2; k++) { for (int j = -radius_ / 2; j <= radius_ / 2; j++) { x1 = Circular(src.cols, x - j); y1 = Circular(src.rows, y - k); sum = sum + kernel_[j + radius_ / 2][k + radius_ / 2] * src.at<uchar>(y1, x1); } } sum = (sum > 255) ? 255 : sum; sum = (sum < 0) ? 0 : sum; dst.at<uchar>(y, x) = sum; } } }
void Main() { Window::SetTitle(L"10.00"); Stopwatch stopwatch; Effect effect; const Font font(50); const Vec2 pos = font(L"00.00").regionCenter(Window::Center()).pos; while (System::Update()) { if ((!stopwatch.isActive() || stopwatch.isPaused()) && Input::MouseL.clicked) { Graphics::SetVSyncEnabled(false); stopwatch.start(); } else if (stopwatch.isActive() && Input::MouseL.clicked) { Graphics::SetVSyncEnabled(false); stopwatch.pause(); } else if (Input::MouseR.clicked) { stopwatch.reset(); } else if (stopwatch.isPaused() && stopwatch.ms() / 10 == 10'00) { Graphics::SetVSyncEnabled(true); effect.add<Firework>(Circular(200, Random(TwoPi)) + Window::Center(), 30); } font(L"{:0>2}.{:0>2}"_fmt, stopwatch.s(), stopwatch.ms() % 1000 / 10).draw(pos); if (effect.hasEffects()) { Graphics2D::SetBlendState(BlendState::Additive); effect.update(); Graphics2D::SetBlendState(BlendState::Default); } else { System::Sleep(4ms); } } }
void ComputeHistograms(Image *img, float sum[4][511], float dif[4][511]) { ulong x, y, p, q; ulong npixels; AdjRel *A; int i, j; Pixel v; A = Circular(1.5); for (i=0; i<4; i++) for (j=0; j<=510; j++){ sum[i][j] = 0.0; dif[i][j] = 0.0; } for(y=1; y<img->nrows-1; y++){ for(x=1; x<img->ncols-1; x++){ p = x + img->tbrow[y]; for (i=1; i <= A->n>>1; i++){ v.x = x + A->dx[i]; v.y = y + A->dy[i]; q = v.x + img->tbrow[v.y]; if (ValidPixel(img,v.x,v.y)){ sum[i - 1][img->val[p] + img->val[q]] += 1.0; dif[i - 1][img->val[p] - img->val[q] + 255] += 1.0; } } } } DestroyAdjRel(&A); npixels = img->ncols * img->nrows; for (i=0; i<4; i++) for (j=0; j<=510; j++){ sum[i][j] /= (float) npixels; dif[i][j] /= (float) npixels; } }
void DiffWatershed(Image *grad, ImageForest *fst, Set *Obj, Set *Bkg, Set *Rm) { AdjRel *A=NULL; GQueue *Q=NULL; Pixel u,v; int i,p,q,n,tmp,Cmax=MaximumValue(grad); Set *aux, *Frontier=NULL; Image *cost=fst->cost,*pred=fst->pred,*label=fst->label,*root=fst->root; n = grad->ncols*grad->nrows; Q = CreateGQueue(Cmax+1,n,cost->val); A = Circular(1.5); if (Rm != NULL) { // Treat removed trees Frontier = ForestRemoval(fst,Rm,A); while (Frontier != NULL) { p = RemoveSet(&Frontier); InsertGQueue(&Q,p); } } /* Trivial path initialization for new seeds */ aux = Obj; while(aux != NULL){ p=aux->elem; if (Q->L.elem[p].color == GRAY) { /* p is also a frontier pixel, but the priority is it as a seed. */ RemoveGQueueElem(Q,p); } label->val[p]=1; cost->val[p]=0; root->val[p]=p; pred->val[p]=NIL; InsertGQueue(&Q,p); aux = aux->next; } aux = Bkg; while(aux != NULL){ p=aux->elem; if (Q->L.elem[p].color == GRAY) { /* p is also a frontier pixel, but the priority is it as a seed. */ RemoveGQueueElem(Q,p); } label->val[p]=0; cost->val[p]=0; root->val[p]=p; pred->val[p]=NIL; InsertGQueue(&Q,p); aux = aux->next; } /* Path propagation */ while (!EmptyGQueue(Q)){ p = RemoveGQueue(Q); u.x = p%grad->ncols; u.y = p/grad->ncols; for (i=1; i < A->n; i++) { v.x = u.x + A->dx[i]; v.y = u.y + A->dy[i]; if (ValidPixel(grad,v.x,v.y)){ q = v.x + grad->tbrow[v.y]; if (Q->L.elem[q].color != BLACK) { tmp = MAX(cost->val[p] , grad->val[q]); if ((tmp < cost->val[q])||(pred->val[q]==p)){ if (Q->L.elem[q].color == GRAY) { RemoveGQueueElem(Q,q); } cost->val[q] = tmp; label->val[q] = label->val[p]; root->val[q] = root->val[p]; pred->val[q] = p; InsertGQueue(&Q,q); } } } } } DestroyGQueue(&Q); DestroyAdjRel(&A); }
/// @brief Create C Cordic Tables and test the results /// @return 0 int main (int argc, char *argv[]) { Cordic_T x1; char str[256]; char *oname; char *p; double d; int a; int i; FILE *FO; for(i=1; i<argc;++i) { p = argv[i]; if(*p != '-') continue; ++p; if(*p == 'o') { oname = argv[++i]; } } if(!oname) { fprintf(stderr,"Usage: %s -o filename [-p]\n",argv[0]); fprintf(stderr,"-o filename is CORDIC C table output file\n"); exit(1); } FO = fopen(oname,"w"); if(FO == NULL) { fprintf(stderr,"Can not open: [%s]\n", oname); exit (1); } fprintf(FO,"#ifndef _CORDIC_INC_H\n"); fprintf(FO,"#define _CORDIC_INC_H\n"); fprintf(FO,"/**\n"); fprintf(FO," @file %s\n", basename(oname)); fprintf(FO," Generated by:[%s]\n", basename(argv[0])); fprintf(FO," On: %s\n", get_date()); fprintf(FO," By Mike Gore 2015, Cordic C Table\n"); fprintf(FO,"*/\n"); dump_tables( FO); fprintf(FO,"#else // CORDIC_TABLE\n"); fprintf(FO,"extern const Cordic_T v_atangrad[];\n"); fprintf(FO,"#endif // CORDIC_TABLE\n"); fprintf(FO,"#endif // _CORDIC_INC_H\n"); printf("// Verify CORDIC table \n"); for(d=0;d<=1;d+=.1) { x1 = FP2Cordic(d); Circular (Cordic_K, 0L, x1); a = (int) 100 * d + 0.000005; // rounding - 0.1 is not exact sprintf(str,"%d Gradians", a); PrintXYZ (str); } printf("// End of CORDIC verify\n"); return (0); }
int main(int argc, char **argv) { timer *t1=NULL,*t2=NULL; Image *img=NULL,*grad=NULL,*marker=NULL; Image *label=NULL; CImage *cimg=NULL; AdjRel *A=NULL; char outfile[100]; char *file_noext; /*--------------------------------------------------------*/ void *trash = malloc(1); struct mallinfo info; int MemDinInicial, MemDinFinal; free(trash); info = mallinfo(); MemDinInicial = info.uordblks; /*--------------------------------------------------------*/ if (argc!=4){ fprintf(stderr,"Usage: watergray <image.pgm> <gradient.pgm> <H>\n"); fprintf(stderr,"image.pgm: grayscale image to overlay the watershed lines on it\n"); fprintf(stderr,"gradient.pgm: gradient image to compute the watershed segmentation\n"); fprintf(stderr,"H: an integer that will be added to the gradient to eliminate irrelevant basins (typically <= 100)\n"); exit(-1); } img = ReadImage(argv[1]); grad = ReadImage(argv[2]); file_noext = strtok(argv[1],"."); // A grayscale marker can be created by any extensive operation: // A value H may be added to eliminate irrelevant basins, for instance. marker = AddValue(grad,atoi(argv[3])); // Watershed from grayscale marker A = Circular(1.0); // try also higher adjacency radii: 1.5, 2.5, etc. t1 = Tic(); label = WaterGray(grad,marker,A); t2 = Toc(); fprintf(stdout,"Processing time in %f ms\n",CTime(t1,t2)); // Draw watershed lines cimg = DrawLabeledRegions(img,label); sprintf(outfile,"%s_result.ppm",file_noext); WriteCImage(cimg,outfile); DestroyImage(&grad); DestroyImage(&img); DestroyImage(&marker); DestroyCImage(&cimg); DestroyImage(&label); DestroyAdjRel(&A); /* ---------------------------------------------------------- */ info = mallinfo(); MemDinFinal = info.uordblks; if (MemDinInicial!=MemDinFinal) printf("\n\nDinamic memory was not completely deallocated (%d, %d)\n", MemDinInicial,MemDinFinal); return(0); }