C + GD kütüphanesi
Sadece eski herhangi bir yere daire çizmek yerine, resimde kırmızı bir şey bulmanın ve etrafına bir daire çizmenin eğlenceli olacağını düşündüm.
İşte elde edilen sonuçların bazı örnekler ile bir kaç fotoğraf arasından Wikimedia Commons :
Ve işte kod. Biraz dağınık, ama takip etmek çok zor değil, umarım:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <gd.h>
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
/* Used for image segmentation */
int floodfill(int *tmp, int i, int w, int id) {
int np=1;
tmp[i]=id;
if (tmp[i-w-1]<0) np+=floodfill(tmp,i-w-1,w,id);
if (tmp[i-w]<0) np+=floodfill(tmp,i-w,w,id);
if (tmp[i-w+1]<0) np+=floodfill(tmp,i-w+1,w,id);
if (tmp[i-1]<0) np+=floodfill(tmp,i-1,w,id);
if (tmp[i+1]<0) np+=floodfill(tmp,i+1,w,id);
if (tmp[i+w-1]<0) np+=floodfill(tmp,i+w-1,w,id);
if (tmp[i+w]<0) np+=floodfill(tmp,i+w,w,id);
if (tmp[i+w+1]<0) np+=floodfill(tmp,i+w+1,w,id);
return np;
}
int main(int argv, char *argc[]) {
FILE *infile,*outfile;
gdImagePtr img;
int *t, *tmp;
int w,h,x,y,r,g,b;
int c,redness,rgb;
int i,np,max,min,thresh;
int xt,yt,n;
int areaID,size,maxID;
double xmin,ymin,xmax,ymax,rad,r0,th;
gdPoint v[33];
/* Check command line and open source JPEG file */
if (argv!=3) return printf("Usage: %s <in.jpg> <out.jpg>\n",argc[0]);
if (!(infile=fopen(argc[1],"r"))) return printf("Can't open <%s>\n",argc[1]);
if (!(img=gdImageCreateFromJpeg(infile))) return printf("Bad JPEG: <%s>\n",argc[1]);
fclose(infile);
/* Extract red pixels and auto-threshold */
w=img->sx;
h=img->sy;
np=w*h;
t=tmp=calloc(np,sizeof(int));
for (max=0,min=255,y=1;y<h-1;y++) {
for (x=1;x<w-1;x++) {
rgb=gdImageGetTrueColorPixel(img,x,y);
r = (rgb&0xff0000)>>16;
g = (rgb&0xff00)>>8;
b = rgb&0xff;
redness = max(0,r-(max(g,b)+abs(g-b)));
if (redness>max) max=redness;
if (redness<min) min=redness;
*t++ = redness;
}
t += 2;
}
thresh = (max+min)/2;
for (t=tmp,i=0;i<np;i++,t++) *t=((*t>thresh)?-1:0);
/* Label each area detected */
areaID=1;
maxID=0;
max=-1;
for (t=tmp,i=0;i<np;i++,t++) {
if (*t<0) {
size=floodfill(tmp,i,w,areaID);
if (size>max) {
max = size;
maxID = areaID;
}
areaID++;
}
}
/* Calculate centre coordinates and area */
if (max>0) {
xt=yt=n=xmax=ymax=0;
xmin=w; ymin=h;
for (t=tmp,y=0;y<h;y++) {
for (x=0;x<w;x++) {
if (*t++==maxID) {
xt+=x;
yt+=y;
n++;
if (x<xmin) xmin=x;
if (y<ymin) ymin=y;
if (x>xmax) xmax=x;
if (y>ymax) ymax=y;
}
}
}
x = xt/(2*n) + (xmax+xmin)/4;
y = yt/(2*n) + (ymax+ymin)/4;
r0 = max(20,min(min(w,h),max(xmax-xmin,ymax-ymin))/2);
}
/* Default circle if nothing found */
else {
x=w/2; y=h/2; r0=min(w,h)/3;
}
/* Draw a red circle */
for (th=4.0,i=0;i<33;i++) {
rad = r0 * (1.2 + (" ,<MYZVSB>@EJIOSWZfgb^bbfgeZTOI@2"[i]-87)/160.0);
v[i].x = x + rad * sin(th);
v[i].y = y + rad * cos(th);
th += 0.22;
}
gdImageSetThickness(img,7);
c = gdImageColorAllocate(img,255,0,0);
gdImageOpenPolygon(img,v,33,c);
/* Output results to file */
printf("Saving...\n");
if (!(outfile=fopen(argc[2],"w"))) {
return printf("Can't open <%s> for writing\n",argc[2]);
}
gdImageJpeg(img,outfile,85);
fclose(outfile);
gdImageDestroy(img);
printf("Finished\n");
return 0;
}
Not: Markdown yorumlarda bağlantımı bozdu, bu yüzden kodun resimdeki tüm kırmızı alanlarını tanımlamak için segmentasyon kullandığını ve daha sonra bunların en büyüğünün etrafına bir daire çizdiğini göstereceğim . Örneğin, bu resim :
aşağıdaki çıktıyı üretir: