सी + जीडी पुस्तकालय
किसी भी पुराने घेरे को आकर्षित करने के बजाय, मैंने सोचा कि चित्र में कुछ लाल खोजने और उसके चारों ओर एक घेरा बनाने में मज़ा आएगा।
यहाँ प्राप्त परिणामों के कुछ उदाहरण हैं के साथ एक कुछ तस्वीरें से विकिमीडिया कॉमन्स :
और यहाँ कोड है। यह थोड़ा गड़बड़ है, लेकिन इसका पालन करना बहुत मुश्किल नहीं है, मुझे उम्मीद है:
#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;
}
नोट: मार्कडाउन ने टिप्पणियों में मेरे लिंक को गड़बड़ कर दिया है, इसलिए मैं सिर्फ यह बताऊंगा कि कोड चित्र में लाल के सभी क्षेत्रों की पहचान करने के लिए विभाजन का उपयोग करता है , और फिर इनमें से सबसे बड़ा घेरा बनाता है। उदाहरण के लिए, यह छवि :
निम्नलिखित उत्पादन का उत्पादन: