एक छवि के संकेत अनुरेखण


17

इस स्टैक स्निपेट में एक छवि लोड करें और उस पर अपना माउस ले जाएँ। एक काला वक्र इस प्रकार है कि रंग कोण, अपने कर्सर बिंदु पर शुरू करने, तैयार किया जाएगा:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><style>canvas{border:1px solid black;}</style>Load an image: <input type='file' onchange='load(this)'><br><br>Max length <input id='length' type='text' value='300'><br><br><div id='coords'></div><br><canvas id='c' width='100' height='100'>Your browser doesn't support the HTML5 canvas tag.</canvas><script>function load(t){if(t.files&&t.files[0]){var e=new FileReader;e.onload=setupImage,e.readAsDataURL(t.files[0])}}function setupImage(t){function e(t){t.attr("width",img.width),t.attr("height",img.height);var e=t[0].getContext("2d");return e.drawImage(img,0,0),e}img=$("<img>").attr("src",t.target.result)[0],ctx=e($("#c")),ctxRead=e($("<canvas>"))}function findPos(t){var e=0,a=0;if(t.offsetParent){do e+=t.offsetLeft,a+=t.offsetTop;while(t=t.offsetParent);return{x:e,y:a}}return void 0}$("#c").mousemove(function(t){function e(t,e){var a=ctxRead.getImageData(t,e,1,1).data,i=a[0]/255,r=a[1]/255,o=a[2]/255;return Math.atan2(Math.sqrt(3)*(r-o),2*i-r-o)}if("undefined"!=typeof img){var a=findPos(this),i=t.pageX-a.x,r=t.pageY-a.y;$("#coords").html("x = "+i.toString()+", y = "+r.toString());var o=parseInt($("#length").val());if(isNaN(o))return void alert("Bad max length!");for(var n=[i],f=[r],h=0;n[h]>=0&&n[h]<this.width&&f[h]>=0&&f[h]<this.height&&o>h;)n.push(n[h]+Math.cos(e(n[h],f[h]))),f.push(f[h]-Math.sin(e(n[h],f[h]))),h++;ctx.clearRect(0,0,this.width,this.height),ctx.drawImage(img,0,0);for(var h=0;h<n.length;h++)ctx.fillRect(Math.floor(n[h]),Math.floor(f[h]),1,1)}});</script>

मैंने केवल Google Chrome में इस स्निपेट का परीक्षण किया है।

उदाहरण के लिए, जब कर्सर लाल से ऊपर होता है, तो वक्र में 0 ° ढलान होता है, लेकिन जब यह पीले से ऊपर होता है, तो इसमें 60 ° ढलान होता है। निर्दिष्ट लंबाई के लिए वक्र जारी रहता है, ह्यू से मिलान करने के लिए लगातार अपने ढलान को बदलता रहता है।

इस छवि को लोड करें और जब आप कर्सर को इस पार करते हैं, तो कर्सर के चारों ओर की रेखा को एक संपूर्ण काउंटर-क्लॉकवाइज़ मोड़ करना चाहिए:

ह्यू कोण

यह और यह कोशिश करने के लिए अन्य स्वच्छ छवियां हैं। (आपको उन्हें बचाने और फिर उन्हें स्निपेट के साथ लोड करने की आवश्यकता होगी। क्रॉस-ऑरिजनल बाधाओं के कारण उन्हें सीधे लिंक नहीं किया जा सकता है।)

यहाँ स्निपेट का एक गैर-छोटा संस्करण है:

चुनौती

एक कार्यक्रम लिखें जो स्निपेट कर रहा है, बस अंतःक्रियात्मक रूप से नहीं। एक छवि लें और (x, y) छवि की सीमा में समन्वय करें, और अधिकतम वक्र लंबाई। जोड़े गए काले वक्र के साथ एक ही छवि को आउटपुट करें जो hue कोण पर शुरू होता है (x, y) और यह तब समाप्त होता है जब यह अधिकतम लंबाई तक पहुँच जाता है या एक छवि सीमा को हिट करता है।

विशेष रूप से, (x, y) पर वक्र शुरू करें और वहां पर कोण को मापें। उस दिशा में एक इकाई (एक पिक्सेल की चौड़ाई) पर जाएं, यह देखते हुए कि आपकी नई स्थिति एक पूर्णांक समन्वय की संभावना नहीं है । वक्र पर एक अन्य बिंदु चिह्नित करने और फिर से ले जाते हैं, निकटतम पिक्सेल से रंग का उपयोग कर (की तरह कुछ का उपयोग कर floorया round, मैं इस ठीक जाँच नहीं लिया जाएगा)। इस तरह से जारी रखें जब तक कि वक्र सीमा से बाहर नहीं जाता है या यह अधिकतम लंबाई से अधिक है। समाप्त करने के लिए, सभी वक्र बिंदुओं को सिंगल ब्लैक पिक्सल्स के रूप में प्लॉट करें (फिर से, निकटतम पिक्सेल का उपयोग करें) छवि पर ओवरले, और इस नई छवि को आउटपुट करें।

"ह्यू एंगल" सिर्फ ह्यू है :

hue = atan2(sqrt(3) * (G - B), 2 * R - G - B)

ध्यान दें कि ग्रेस्केल मूल्यों के लिए जो तकनीकी रूप से एक ह्यू नहीं है, यह 0 देता है, लेकिन यह ठीक है।

(यह सूत्र उपयोग करता है atan2जो अधिकांश अंतर्निहित गणित पुस्तकालयों में है। आर, जी, बी 0 से 1 तक हैं, 0 से 255.5 तक नहीं)

  • आप किसी भी सामान्य दोषरहित छवि फ़ाइल प्रारूप के साथ-साथ किसी भी छवि लाइब्रेरी का उपयोग कर सकते हैं।
  • स्टडिन या कमांड लाइन से इनपुट लें, या छवि फ़ाइल नाम, x और y, और अधिकतम लंबाई के लिए तर्कों के साथ एक फ़ंक्शन लिखें।
  • अधिकतम लंबाई और x और y हमेशा nonnegative पूर्णांक होते हैं। आप मान सकते हैं कि x और y सीमा में हैं।
  • अपनी पसंद के नाम के साथ आउटपुट छवि को सहेजें या बस इसे प्रदर्शित करें।
  • आपके कार्यान्वयन को स्निपेट से बिल्कुल मेल नहीं खाता है। कुछ अलग गोलाई / गणना पद्धति के कारण थोड़े अलग स्थानों में कुछ पिक्सेल ठीक हैं। (अराजक मामलों में यह घटता है जो प्रमुख रूप से भिन्न होता है, लेकिन जब तक वे नेत्रहीन सही दिखते हैं, यह ठीक है।)

स्कोरिंग

बाइट्स में सबसे छोटी सबमिशन जीत जाती है।


1
स्निपेट फ़ायरफ़ॉक्स में पूरी तरह से टूट गया है।
यपनीपं

स्निपेट भी सफारी में काम नहीं करता है। (कूल चैलेंज हालांकि, +1)
एलेक्स ए।

@ केल्विन के शौक क्या हम चैट कर सकते हैं? chat.stackexchange.com/rooms/22029/…
BrainSteel

जवाबों:


2

MATLAB, 136

function t(g,x,y,l)
m=imread(g);imshow(m); h=2*pi*rgb2hsv(m);h=h(:,:,1);s=streamline(cos(h),-sin(h),x,y,[1,l]);set(s,'LineW',1,'Co','k');

सेटअप के अधिकांश और इस तरह @sanchises से नकल की, लेकिन मैं इसके बजाय streamlineपथ की गणना और आकर्षित करने के लिए उपयोग करता हूं । यह एंटीअलियास लाइन को करता है, और बिलिनियर इंटरपोलेशन का उपयोग करता है, बजाय निकटतम-पड़ोसी के रूप में निर्दिष्ट।


5

सी एसडीएल के साथ, 549 516 बाइट्स

मैं यह पार्टी शुरू करूँगा! किसी कारण के लिए, मुझे आज रात गोल्फ में हाथ आजमाने का मन हुआ। आप लोग जो करते हैं वह कठिन है ... अगर एक चीज है जो मुझे इस साइट पर दिखाई नहीं देती है, तो यह एसडीएल है। मुझे अभी पता चला है कि क्यों हो सकता है। यह विशेष स्निपेट SDL2 और SDL1.2 दोनों का अनुपालन करता है, लेकिन अत्याचारी है। जैसे कहा जाता है f("imagename.bmp", xcoord, ycoord, max_length);। यह एक फ़ाइल को उसी नाम से सेव करता है जैसा कि तर्कों में दिया गया है। आउटपुट ओपी के कोड स्निपेट के समान प्रतीत होता है, लेकिन "फ़ज़ियर"। मैं इसे थोड़ा बाद में ठीक करने की कोशिश कर सकता हूं।

#include"SDL.h"
f(char*C,x,y,m){SDL_Surface*P=SDL_LoadBMP(C);int p=P->pitch,i=P->format->BytesPerPixel,q=0;double X=x,Y=y,f=255,R,G,B,h;Uint8*Q,d=1,r,g,b,k;while(d){Q=P->pixels+y*p+i*x;SDL_GetRGB(i==4?*(Uint32*)Q:i==3?SDL_BYTEORDER==4321?*Q<<16|Q[1]<<8|Q[2]:*Q|Q[1]<<8|Q[2]<<16:i==2?*(Uint16*)Q:*Q,P->format,&r,&g,&b);R=r/f;G=g/f;B=b/f;h=atan2(sqrt(3)*(G-B),2*R-G-B);for(k=0;k<i;k++)Q[k]=0;X+=cos(h);Y-=sin(h);if((int)X-x|(int)Y-y)q++;x=X;y=Y;d=x<0|x>=P->w|y<0|y>=P->h|q>=m?0:1;}SDL_SaveBMP(P,C);SDL_FreeSurface(P);}

यहाँ यह सब अप्रकाशित है:

#include"SDL.h"
f(char*C,x,y,m){
    SDL_Surface*P=SDL_LoadBMP(C);
    int p=P->pitch,i=P->format->BytesPerPixel,q=0;
    double X=x,Y=y,f=255,R,G,B,h;
    Uint8*Q,d=1,r,g,b,k;
    while(d){
        Q=P->pixels+y*p+i*x;
        SDL_GetRGB(i==4?*(Uint32*)Q:i==3?SDL_BYTEORDER==4321?*Q<<16|Q[1]<<8|Q[2]:*Q|Q[1]<<8|Q[2]<<16:i==2?*(Uint16*)Q:*Q,P->format,&r,&g,&b);
        R=r/f;
        G=g/f;
        B=b/f;
        h=atan2(sqrt(3)*(G-B),2*R-G-B);
        for(k=0;k<i;k++)Q[k]=0;
        X+=cos(h);
        Y-=sin(h);
        if((int)X-x|(int)Y-y)q++;
        x=X;y=Y;
        d=x<0|x>=P->w|y<0|y>=P->h|q>=m?0:1;
    }
    SDL_SaveBMP(P,C);
    SDL_FreeSurface(P);
}

मुझे ध्यान देना चाहिए कि इसे पार मंच बनाने के लिए देखभाल की गई थी - ईमानदारी के हित में, यह मेरी मशीन के लिए इसे हार्डकोड करना अच्छा नहीं लगा, भले ही यह पर्याप्त संख्या में बाइट्स काट दिया हो। फिर भी, मुझे लगता है कि कुछ चीजें यहां बहुत ही शानदार हैं, और मैं इसे बाद में फिर से देखूंगा।

संपादित करें -------

यह आईएस ग्राफिकल आउटपुट है, आखिरकार ... मैं उन छवियों के साथ अपडेट करूंगा जो मुझे समय-समय पर दिलचस्प लगते हैं।

f("HueTest1.bmp", 270, 40, 200);

HueTest1.bmp

f("HueTest2.bmp", 50, 50, 200);

HueTest2.bmp

f("HueTest3.bmp", 400, 400, 300);

HueTest3.bmp


3

पायथन, 203 172

from scipy.misc import*
def f(i,x,y,l):
 a=imread(i);Y,X,_=a.shape;o=a.copy()
 while(X>x>0<y<Y<[]>l>0):r,g,b=a[y,x]/255.;o[y,x]=0;l-=1;x+=2*r-g-b;y-=3**.5*(g-b);imsave(i,o)

नमूना उत्पादन: यहाँ छवि विवरण दर्ज करें

के साथ बुलाना f("image.jpg", 400, 400, 300)

मैंने आयात के लिए बहुत सारे पात्रों को बर्बाद कर दिया है, अगर किसी के पास इसे सुधारने के लिए सुझाव हैं। 3.0 में काम नहीं हो सकता


एक त्वरित नज़र से sqrt(3) -> 3**.5:? मैं हालांकि आयात के लिए कुछ भी नहीं सोच सकता।
Sp3000

अच्छा है! जो भविष्य में उपयोगी होगा।
grovesNL

3

MATLAB, 186 172

खेल चालू है ! t('YourImage.ext',123,456,100')किसी भी प्रकार के MATLAB समर्थन की छवि के लिए कॉल करें (x, y) = (123,456) और अधिकतम लंबाई 100 पर शुरू। प्रारंभिक स्थिति बिल्कुल सही और निचले किनारों पर नहीं हो सकती है (जिससे मुझे दो बाइट का खर्च होगा), इसलिए किनारे पर शुरू, कुछ की तरह का उपयोग करेंx=799.99 में शुरू करने के लिए x=800। अनुक्रमण 1 से शुरू होता है, 0 पर नहीं।

कोड:

function t(g,x,y,l)
m=imread(g);[Y,X,~]=size(m);h=2*pi*rgb2hsv(m);while(x>0&x<X&y>0&y<Y&l)
p=ceil(x);q=ceil(y);m(q,p,:)=0;a=h(q,p);x=x+cos(a);y=y-sin(a);l=l-1;end
imshow(m)

संशोधन:

  • पिछले से अगले पिक्सेल में लाइन से बदलकर बस एक पिक्सेल पर डॉट लगाना, क्योंकि लाइन पिक्सेल से अधिक लंबी नहीं होगी! अभी भी इसका उपयोग कर lineरहा है कि मैं एक पिक्सेल का उत्पादन करने के लिए सबसे छोटा कोड है।
  • Coविस्तार करने के लिए , काले से नीले रंग को बदल दियाColor (जो MATLAB स्वचालित रूप से करता है)
  • अगली स्थिति की गणना करने और एक बिंदु बनाने का क्रम बदल गया, क्योंकि मुझे @grovesNL के लिए धन्यवाद महसूस हुआ कि मैं वास्तव में सीमा से बाहर आ रहा था क्योंकि मैं स्थिति बदलने के बाद सीमा की जाँच कर रहा था ।
  • रेखांकन लाइनों को आरजीबी मैट्रिक्स से 0 पर सेट करने और उसके बाद प्रदर्शित करने के लिए परिवर्तित।

काली रेखा कैंडी


नहीं कर रहे हैं x=0या y=0संभवतः वैध पदों?
grovesNL

इसके अलावा, यह 166 बाइट्स कैसे है?
ग्रूव्सएनएल

@grovesNL क्षमा करें, गलती से functionहेडर के बिना मेरे परीक्षण संस्करण को गिना गया । विशिष्ट को शून्य-आधारित या एक-आधारित अनुक्रमण की आवश्यकता नहीं थी, इसलिए मैं MATLAB के एक-आधारित का उपयोग कर रहा हूं, इसलिए नहीं, x=0या y=0इस कार्यक्रम में मान्य नहीं है।
सेंचुरी

आह, मैं भूल गया कि MATLAB एक-आधारित था (यह कुछ समय रहा है)। लेकिन मुझे लगता है कि इसके बजाय बना x=Xऔर y=Yमान्य हो सकता है ?
grovesNL

1
हा! आप अपने खुद के खेल पर मारो, मेरे MATLAB समाधान केवल 135 वर्ण है!
19

1

प्रसंस्करण, 323 वर्ण

void h(String f,float x,float y,float m){PImage i=loadImage(f);PImage i2=loadImage(f);while(m>0){color c=i.get((int)x,(int)y);float r=red(c)/255;float g=green(c)/255;float b=blue(c)/255;float h=atan2(sqrt(3)*(g-b),2*r-g-b);float dx=cos(h);float dy=-sin(h);m-=1;x+=dx;y+=dy;i2.set((int)x,(int)y,color(0));}i2.save("o.png");}

व्हॉट्सएप के साथ:

void h(String f, float x, float y, float m) {
  PImage i = loadImage(f);
  PImage i2 = loadImage(f);

  while (m > 0) {

    color c = i.get((int)x, (int)y);
    float r = red(c)/255;
    float g = green(c)/255;
    float b = blue(c)/255;
    float h = atan2(sqrt(3) * (g - b), 2 * r - g - b);

    float dx = cos(h);
    float dy = -sin(h);

    m-= 1;
    x += dx;
    y += dy;

    i2.set((int)x, (int)y, color(0));
  }

  i2.save("o.png");
}

छवि का पता लगाया

मुझे यकीन है कि मैं इसे और छोटा कर सकता हूं, लेकिन यह अभी के लिए काम करता है।


0

जावास्क्रिप्ट 414

function P(G,x,y,l){
I=new Image()
I.onload=function(){d=document,M=Math,C=d.createElement('canvas')
d.body.appendChild(C)
w=C.width=I.width,h=C.height=I.height,X=C.getContext('2d')
X.drawImage(I,0,0)
D=X.getImageData(0,0,w,h),d=D.data,m=255,i=0
for(;l--;i=(w*~~y+~~x)*4,r=d[i]/m,g=d[i+1]/m,b=d[i+2]/m,H=M.atan2(M.sqrt(3)*(g-b),2*r-g-b),d[i]=d[i+1]=d[i+2]=0,x+=M.cos(H),y-=M.sin(H))
X.putImageData(D,0,0)}
I.src=G}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.