स्क्वायर, सर्कल, त्रिकोण,… गियर?


69

अल्गोडू और पेंट का उपयोग करके मैंने इन छह 300 × 300 को चार सुविधाजनक आकृतियों की मोनोक्रोमैटिक छवियां बनाईं:

चित्र 1 चित्र 2 चित्र 3 छवि 4 चित्र 5 छवि 6

छवियों के इस वर्ग में निम्नलिखित गुण हैं:

  • वे हमेशा 300 × 300 पिक्सल, मोनोक्रोमैटिक (केवल काले और सफेद) होते हैं, और वास्तव में चार सफेद क्षेत्र होते हैं जो एक वर्ग, एक चक्र, एक त्रिकोण और एक गियर के अनुरूप होते हैं।
  • आकार कभी भी एक-दूसरे को ओवरलैप या स्पर्श नहीं करते हैं, न ही वे छवि सीमा को छूते हैं या सीमा से बाहर जाते हैं।
  • आकृतियों का आकार हमेशा समान होता है, लेकिन उन्हें किसी भी तरह से घुमाया और तैनात किया जा सकता है।

(आकृतियों में भी समान क्षेत्र होते हैं, हालांकि जब इस तरह के रैस्टर्ड होते हैं तो उनके पिक्सेल काउंट बिल्कुल समान होने की संभावना नहीं होती है।)

चुनौती

इस तरह की छवि के फ़ाइल नाम में ले जाने वाले सबसे छोटे प्रोग्राम या फ़ंक्शन को लिखें और सभी श्वेत पिक्सेल चालू कर दें ...

  • लाल (255, 0, 0)अगर वे वर्ग में हैं।
  • नीला (0, 0, 255)यदि वे चक्र में हैं।
  • (0, 255, 0)यदि वे त्रिभुज में हों तो हरा ।
  • पीला (255, 255, 0)अगर वे गियर में हैं।

जैसे

छवि 1 रंग में

विवरण

आपका कार्यक्रम प्रभावी रूप से सभी संभव इनपुट छवियों के लिए काम करना चाहिए। (केवल मान्य 300 × 300 मोनोक्रोमैटिक छवियां इनपुट होंगी।) मैंने जो छह छवियां प्रदान की हैं, वे केवल उदाहरण हैं, आप अपने कार्यक्रम में उनके आउटपुट को हार्डकोड नहीं कर सकते हैं।

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

जब तक आप कलर स्कीम से चिपके रहते हैं तब तक इनपुट और आउटपुट के लिए आप किसी भी सामान्य दोषरहित इमेज फाइल फॉर्मेट का उपयोग कर सकते हैं।

आप छवि फ़ाइल नाम को एक फ़ंक्शन तर्क के रूप में, स्टड से, या कमांड लाइन से ले सकते हैं। आउटपुट इमेज को एक नई फाइल, एक ही फाइल में, या केवल प्रदर्शित किया जा सकता है।

स्कोरिंग

सबसे कम बाइट्स के साथ सबमिशन जीत जाता है। मैं उनकी वैधता निर्धारित करने के लिए अतिरिक्त छवियों के साथ प्रस्तुतियाँ का परीक्षण कर सकता हूं।


क्या हम मान सकते हैं कि इनपुट ब्लैक एंड व्हाइट है जिसमें कोई एंटी-एलियासिंग नहीं है? यदि नहीं, तो क्या हम एंटी-एलियास इनपुट से एंटी-एलियासिंग निकाल सकते हैं?
जॉन ड्वोरक

@JDDvorak हां। मोनोक्रोमैटिक से मेरा मतलब केवल काले और सफेद से है, इसलिए एंटी-एलियासिंग नहीं हो सकता है।
केल्विन के शौक

1
क्या हमें किसी फ़ाइल एक्सटेंशन की तुलना में अधिक विशिष्ट इनपुट प्रारूप की आवश्यकता है? अर्थात्, मैं मुझे किसी भी टिप्पणी के बिना एक ASCII PBM इनपुट चाहूँगा ।
जॉन ड्वोरक

12
इसलिए ... मैं इसे हल करने की कोशिश कर रहा था, और मैं इस छवि के साथ समाप्त हुआ । नहीं सच में यकीन है कि कैसे, लेकिन हे, यह फैंसी लग रहा है। : पी
दरवाज़े

2
मैं अपना समाधान पोस्ट नहीं करना चाहता क्योंकि यह एल के समान ही विचार है। लेकिन मैं सिर्फ इतना कहना चाहता हूं कि यह करना एक सुखद चुनौती थी :)
क्रिस बर्ट-ब्राउन

जवाबों:


8

जे - 246,224 185 बाइट्स

load'viewmat'
(viewmat~0,(255*4 3$_2|.#:3720)/:/:@(<([:}.(>./%+/%#)@:(+/&:*:@(-"1)+/%#)@(4$.$.@:=)&>)<"0@~.@,))@(~.@,i.])@(>./**@{.)@((0,(,-)#:>:i.3)&|.)^:_@(*i.@:$)@(0<readimg_jqtide_)

यह एक मजेदार था!

मैंने "सबसे बड़े कमरे में हूँ" चुनौती के लिए उपयोग किए गए जुड़े-पुर्जे वाले हिस्से का पुन: उपयोग किया , और प्रत्येक घटक के केंद्र में सभी बिंदुओं की औसत और अधिकतम दूरी के बीच के अनुपात का उपयोग किया। मैं इसके लिए बस गया, क्योंकि यह पैमाने और रोटेशन दोनों अपरिवर्तनीय है, और स्पष्ट रूप से बहुत अच्छा है कि दिए गए आकृतियों के बीच अंतर कर सकें। इस मान को निम्न से उच्च स्तर पर क्रमबद्ध करने से मुझे आदेश सर्कल, गियर, वर्ग और त्रिकोण मिलता है, जिसका उपयोग कॉलर्मैप को अनुमति देने के लिए किया जाता है।

व्यूअर एडऑन का उपयोग करके परिणाम प्रदर्शित करता है। फ़ाइल रीडिंग और आउटपुट को छोड़कर कोई टूलबॉक्स उपयोग नहीं किया जाता है।

रोबस्टनेस की आवश्यकता नहीं लगती है, यह 18 बाइट्स लेता है। 2 अधिक अनावश्यक रिक्त स्थान, प्रतिस्थापित &.>द्वारा &>में ratioऔर &.:से &:एक और 2 बाइट्स के लिए dcent में।

( ) के compबजाय स्थानांतरण का उपयोग करने की कमी और प्रदर्शन दोनों में भारी लाभ । इस तरह से छवि को 3x3 विंडो के साथ स्कैन करने के बजाय सभी 8 दिशाओं में दोहराया और स्थानांतरित किया गया है।cut;.

idसमारोह के लिए हास्यास्पद जटिल क्या यह करने के लिए जरूरी था। अब यह अद्वितीय संख्याओं की एक सरणी के साथ छवि को गुणा करके वस्तुओं में आईडी के पिक्सेल को असाइन करता है, इसलिए बीजी को शून्य पर सेट करता है।

कोड को थोड़ा और समझाया गया:

load'viewmat'                                 NB. display only
imnames =: < ;. _2 (0 : 0)
C6IKR.png
DLM3y.png
F1ZDM.png
Oa2O1.png
YZfc6.png
chJFi.png
)

images =: (0<readimg_jqtide_) each imnames    NB. read all images in boxed array

id =: *i.@:$                                  NB. NB. assign one number to each non-background (non-zero) pixel
comp =: (>./ * *@{.)@shift^:_@id              NB. 8 connected neighbor using shift
  shift =: (>,{,~<0 _1 1)&|.                  NB. generate the original, and 8 shifted versions (automatically padding and cropping).
result =: comp each images                    NB. Execute comp verb for each image
col =: (~.@, i. ])                            NB. Color: give each component and BG a separate color.

NB. BG in 0, 0 Get all max distance to center % mean distance to center ratios
ratio  =: (< ([:}.rat@:dcent@getInd &>)  <"0@~.@,)
  getInd =: 4 $. $.@:=                        NB. get indices for component y in array x
  dcent  =: +/&.:*:@(-"1) +/%#                NB. distence from center each point
  rat    =: >./ % +/%#                        NB. ratio from distances

cm=: (255*4 3$_2|.#:3720)                     NB. colormap (except black).
(viewmat~ 0,cm /: /:@ratio )@col each result  NB. for each image, show the result, permuting the colormap according to ratio's

NB. almostgolf this
P1 =: (>./**@{.)@((0,(,-)#:>:i.3)&|.)^:_@(*i.@:$)@(0<readimg_jqtide_) NB. reading till components
P2 =: (<([:}.(>./%+/%#)@:(+/&:*:@(-"1)+/%#)@(4$.$.@:=)&>)<"0@~.@,) NB. recognition: get fraction mean vs max distance to center per component, toss BG.     
P3 =: (viewmat~0,(255*4 3$_2|.#:3720)/:/:@P2)@(~.@,i.])@P1    NB. piece together : permute colormap, display components

NB. seriousgolf
load'viewmat'
f =:(viewmat~0,(255*4 3$_2|.#:3720)/:/:@(<([:}.(>./%+/%#)@:(+/&:*:@(-"1)+/%#)@(4$.$.@:=)&>)<"0@~.@,))@(~.@,i.])@((>./**@{.)@shift^:_)@(*i.@:$)@(0<readimg_jqtide_)
NB. example usage:
f&> imnames NB. do for all images

यह एक बार विस्तार से समझाने के लिए थोड़ा लंबा है, लेकिन रुचि होने पर करेंगे।


ऊपरी दाएं पिक्सेल को bg होने की गारंटी है। ओपी के अनुसार "आकार कभी भी एक-दूसरे को ओवरलैप या स्पर्श नहीं करते हैं, न ही वे छवि सीमा को छूते हैं या सीमा से बाहर जाते हैं।"
डॉ। बिसरिसेर

धन्यवाद, यह उपयोगी है। (वास्तव में मेरा मतलब ऊपरी पिक्सेल छोड़ दिया गया था, जो सबसे पहले उठा हुआ है)। यह बैकग्राउंड डिटेक्शन (22 बाइट्स) को बंद कर देता है।
8

नाटकीय रूप से कम लंबाई, और प्रदर्शन में वृद्धि :)
jpjacobs

29

गणितज्ञ, 459 392 बाइट्स

f=(d=ImageData@Import@#/.{a_,_,_}:>a;(For[a={};b={#&@@d~Position~1},b!={},c=#&@@b;b=Rest@b;d[[##&@@c]]=0;a~AppendTo~c;If[Extract[d,c+#]==1,b=b⋃{c+#}]&/@{e={1,0},-e,e={0,1},-e}];m=1.Mean@a;m=#-m&/@a;n=Count[Partition[Norm/@SortBy[m,ArcTan@@#&],300,1,1],l_/;l[[150]]==Max@l];(d[[##&@@#]]=Round[n^.68])&/@a)&/@Range@4;Image[d/.n_Integer:>{{0,0,0},,{0,1,0},{1,0,0},,,,{1,1,0},{0,0,1}}[[n+1]]])&

Ungolfed:

f = (
 d = ImageData@Import@# /. {a_, _, _} :> a;
 (
    For[a = {}; b = {# & @@ d~Position~1},
     b != {},
     c = # & @@ b;
     b = Rest@b;
     d[[## & @@ c]] = 0;
     a~AppendTo~c;
     If[Extract[d, c + #] == 1, 
        b = b ⋃ {c + #}] & /@ {e = {1, 0}, -e, e = {0, 1}, -e}
     ];
    m = 1. Mean@a; m = # - m & /@ a;
    n = 
     Count[Partition[Norm /@ SortBy[m, ArcTan @@ # &], 300, 1, 1], 
      l_ /; l[[150]] == Max@l];
    (d[[## & @@ #]] = Round[n^.68]) & /@ a
    ) & /@ Range@4;
 Image[d /. 
   n_Integer :> {{0, 0, 0}, , {0, 1, 0}, {1, 0, 0}, , , , {1, 1, 
       0}, {0, 0, 1}}[[n + 1]]]
) &

मैं 6 और बाइट्स को बदलकर बचा सकता m=1.Mean@a;m=#-m&/@a;था m=#-Mean@a&/@a;, लेकिन यह निष्पादन के समय को काफी बढ़ा देता है, जो कि परीक्षण के लिए कष्टप्रद है। (ध्यान दें, यह दो अनुकूलन हैं: Mean@aलूप से बाहर निकलने की गणना करना और फ्लोटिंग पॉइंट नंबरों के बजाय सटीक प्रतीकात्मक प्रकारों का उपयोग करना। दिलचस्प बात यह है कि हर पुनरावृत्ति में माध्य की तुलना में सटीक प्रकारों का उपयोग बहुत अधिक महत्वपूर्ण है।

तो यह दृष्टिकोण संख्या तीन है:

  • बाढ़ से क्षेत्रों का पता लगाएं।
  • सभी पिक्सेल निर्देशांक औसत से प्रत्येक क्षेत्र के अनुमानित केंद्र का पता लगाएं।
  • अब आकार के सभी पिक्सेल के लिए आइए उस केंद्र से बनाम कोण से दूरी तय करें:

    यहाँ छवि विवरण दर्ज करें

    त्रिभुज में 3 स्पष्ट मैक्सिमा है, वर्ग 4, गियर 16, और सर्कल में टन है, निरंतर त्रिज्या के बारे में उतार-चढ़ाव के कारण।

  • हम 300 पिक्सेल (कोण द्वारा आदेशित) के स्लाइसों को देखकर मैक्सिमा की संख्या पाते हैं, और उन स्लाइसों की गणना करते हैं जहां स्थिति में पिक्सेल 150अधिकतम है।
  • तब हम बस सभी पिक्सल को चोटियों की संख्या के आधार पर रंगते हैं (सर्कल 16 से अधिक है, और आमतौर पर स्लाइस के आकार के कारण लगभग 20 चोटियां होती हैं)।

सिर्फ रिकॉर्ड के लिए, अगर मैं एल के विचार का उपयोग करता हूं, और किसी भी पिक्सेल और केंद्र के बीच सबसे बड़ी दूरी के आधार पर क्षेत्रों को क्रमबद्ध करता हूं, तो मैं 342 बाइट्स में यह कर सकता हूं:

f=(d=ImageData@Import@#/.{a_,_,_}:>a;MapIndexed[(d[[##&@@#]]=#&@@#2)&,SortBy[(For[a={};b={#&@@d~Position~1},b!={},c=#&@@b;b=Rest@b;d[[##&@@c]]=0;a~AppendTo~c;If[Extract[d,c+#]==1,b=b⋃{c+#}]&/@{e={1,0},-e,e={0,1},-e}];a)&/@Range@4,(m=Mean@#;Max[1.Norm[#-m]&/@#])&],{2}];Image[d/.n_Integer:>{{0,0,0},{0,0,1},{1,1,0},{1,0,0},{0,1,0}}[[n+1]]])&

लेकिन मैं उस के साथ प्रतिस्पर्धा करने का इरादा नहीं करता, जब तक कि बाकी सभी अपने स्वयं के मूल एल्गोरिदम का उपयोग कर रहे हैं, बजाय दूसरों के उन लोगों को नीचे गिराने के।


सबसे दिलचस्प समाधान!
CSharpie

25

जावा, 1204 1132 1087 1076

बस खुद को साबित करने के लिए कि मैं यह कर सकता हूं।

मैंने फ़ंक्शन घोषणाओं के ठीक बगल में आयात शामिल किया; इस कार्य के लिए इन्हें कक्षा के बाहर रहना होगा:

import java.awt.*;import java.awt.image.*;import java.io.*;import java.util.*;import javax.imageio.*;

BufferedImage i;Set<Point>Q;void p(String a)throws Exception{i=new BufferedImage(302,302,1);i.getGraphics().drawImage(ImageIO.read(new File(a)),1,1,null);Set<Set<Point>>S=new HashSet<>();for(int y=0;y<300;y++){for(int x=0;x<300;x++){if(!G(x,y)){Point p=new Point(x,y);Q=new HashSet<>();if(!S.stream().anyMatch(s->s.contains(p)))S.add(f(x,y));}}}Object[]o=S.stream().sorted((p,P)->c(p)-c(P)).toArray();s(o[0],255);s(o[1],255<<16);s(o[2],0xFF00);s(o[3],0xFFFF00);ImageIO.write(i.getSubimage(1,1,300,300),"png",new File(a));}boolean G(int x,int y){return i.getRGB(x,y)!=-1;}Set<Point>f(int x,int y){Point p=new Point(x,y);if(!Q.contains(p)&&!G(x,y)){Q.add(p);f(x-1,y);f(x+1,y);f(x,y-1);f(x,y+1);}return Q;}int c(Set<Point>s){return(int)s.stream().filter(p->G(p.x-2,p.y-1)||G(p.x-2,p.y+1)||G(p.x+1,p.y-2)||G(p.x-1,p.y-2)||G(p.x+2,p.y-1)||G(p.x+2,p.y+1)||G(p.x+1,p.y+2)||G(p.x-1,p.y+2)).count();}void s(Object o,int c){((Set<Point>)o).stream().forEach(p->{i.setRGB(p.x,p.y,c);});}

Ungolfed (और runnable; यानी बॉयलरप्लेट जोड़ा गया):

import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
import javax.imageio.ImageIO;

public class SquareCircleTriangleGear {
    public static void main(String[]args){
        try {
            new SquareCircleTriangleGear().p("filepath");
        } catch (Exception ex) {
        }
    }
    BufferedImage i;
    Set<Point>Q;
    void p(String a)throws Exception{
        i = new BufferedImage(302,302,BufferedImage.TYPE_INT_RGB);
        i.getGraphics().drawImage(ImageIO.read(new File(a)),1,1,null);
        Set<Set<Point>>set=new HashSet<>();
        for(int y=0;y<300;y++){
            for(int x = 0;x<300;x++){
                if(i.getRGB(x,y)==-1){
                    Point p = new Point(x,y);
                    Q=new HashSet<>();
                    if(!set.stream().anyMatch((s)->s.contains(p))){
                        set.add(fill(x,y));
                    }
                }
            }
        }
        Object[]o=set.stream().sorted((p,P)->c(p)-c(P)).toArray();
        s(o[0],0x0000FF);
        s(o[1],0xFF0000);
        s(o[2],0x00FF00);
        s(o[3],0xFFFF00);
        ImageIO.write(i.getSubImage(1,1,300,300), "png", new File(a));
    }
    Set<Point>fill(int x, int y){
        Point p=new Point(x,y);
        if(!Q.contains(p)&&!i.getRGB(x,y)!=-1) {
        Q.add(p);
            fill(x-1,y);
            fill(x+1,y);
            fill(x,y-1);
            fill(x,y+1);
        }
        return Q;
    }
    int c(Set<Point>s){return (int)s.stream().filter(p->isBoundary(p.x,p.y)).count();}
    boolean isBoundary(int x, int y){
        return i.getRGB(x-2,y-1)!=-1||i.getRGB(x-2,y+1)!=-1||i.getRGB(x+1,y-2)!=-1||
               i.getRGB(x-1,y-2)!=-1||i.getRGB(x+2,y-1)!=-1||i.getRGB(x+2,y+1)!=-1||
               i.getRGB(x+1,y+2)!=-1||i.getRGB(x-1,y+2)!=-1;
    }
    void s(Object o,int c){
        ((Set<Point>)o).stream().forEach(p->{i.setRGB(p.x,p.y,c);});
    }
}

हर बार जब हम "छेद" तक पहुँचते हैं, तो हर बार छवि के हर पिक्सेल पर बाढ़ और बाढ़-भरने का काम करता है। हम एक के रूप में प्रत्येक बाढ़ भरण परिणाम जोड़ने के Set<Point>एक करने के लिए Set। फिर हम निर्धारित करते हैं कि कौन सा आकार कौन सा है। यह आकृति की सीमा पिक्सेल की संख्या को देखकर किया जाता है। मैंने एक काली टाइल से दूर एक नाइट के रूप में सीमा को परिभाषित किया, क्योंकि यह रोटेशन और इस तरह के बीच अधिक स्थिर रहेगा। जब हम ऐसा करते हैं, तो यह स्पष्ट हो जाता है कि आकृतियों को उस मूल्य से क्रमबद्ध किया जा सकता है: सर्कल, स्क्वायर, त्रिकोण, गियर। इसलिए मैंने उस आकृति के सभी पिक्सल को सही रंग के अनुसार सॉर्ट और सेट किया।

ध्यान दें कि मैं जो छवि लिख रहा हूं, वह सीधे फ़ाइल से नहीं ली गई है, क्योंकि अगर मैं ऐसा कर रहा था, तो जावा छवि को काले और सफेद के रूप में व्यवहार करेगा और रंगों से भरने से काम नहीं चलेगा। इसलिए मुझे अपनी खुद की छवि बनानी होगी TYPE_INT_RGB(जो है 1)। यह भी ध्यान दें कि मैं जिस छवि पर काम कर रहा हूं वह 302है 302; ऐसा इसलिए है कि नाइट की दूरी एल्गोरिथ्म को छवि पर आउट-ऑफ-बाउंड्स पढ़ने की कोशिश करने के बारे में चिंता करने की आवश्यकता नहीं है। मैं कॉल करके इस विसंगति को आकार में ठीक करता हूं i.getSubImage(1,1,300,300)नोट: जब मैं चित्र अपलोड करता हूं, तो मैं इसे ठीक करना भूल सकता हूं, ऐसे में चित्र 2 पिक्सेल बहुत चौड़े हैं, लेकिन इस तथ्य को छोड़कर, उन्हें सही होना चाहिए

फ़ंक्शन उस फ़ाइल को अधिलेखित कर देगा जिसका पथ पास है। आउटपुट:

यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें


वर्ग नाम को छोटा करने के साथ-साथ "a" या समान करने के लिए मुख्य विधि में args द्वारा कुछ वर्णों को सहेज सकते हैं।
रयान

@ रेयान को गिनती में नहीं गिना जाता। मैं केवल आयात + कार्यों की गणना करता हूं, जैसा कि प्रश्न द्वारा अनुमत है।
जस्टिन

मुझे लगता है कि मैं 1000 बाइट्स के तहत इसे प्राप्त करने में सक्षम हो सकता हूं। कोशिश करने का समय होने पर बाद में इस पर काम करना चाहिए।
जस्टिन

20

अजगर, 571 567 528 बाइट्स

इसी तरह क्विनकुंक्स के समाधान के लिए, यह प्रत्येक आकृति को 1 से 4 तक के सूचकांक के साथ बाढ़ से शुरू करता है। यह फिर उनके बाउंडिंग सर्कल के त्रिज्या द्वारा आकृतियों की पहचान निर्धारित करता है। एक रंग-पैलेट का निर्माण तदनुसार किया जाता है और छवि को अनुक्रमित-रंग छवि के रूप में सहेजा जाता है।

संपादित करें: इस तथ्य को याद किया कि आकृतियों को छवि सीमा को नहीं छूने की गारंटी है। कम है, तो यह है!

from PIL.Image import*;from numpy import*
I=open(sys.argv[1]).convert("P")
D=list(I.getdata())
W=300;R=range(W*W);N=range(5)
O=[[0,i,array([0,0])]for i in N];n=0
for i in R:
 if D[i]>4:
    n+=1;S=[i]
    while S:
     j=S.pop()
     if D[j]>4:D[j]=n;O[n][0]+=1;O[n][2]+=j%W,j/W;S+=[j+1,j-1,j+W,j-W]
for o in O[1:]:o[2]/=o[0];o[0]=0
for i in R:
 if D[i]:o=O[D[i]];v=(i%W,i/W)-o[2];o[0]=max(o[0],dot(v,v))
O.sort()
C=[0]*5+[255]*3+[0,255,0,0]*2;P=C[:]
for i in N:j=3*O[i][1];P[j:j+3]=C[3*i:3*i+3]
I.putdata(D);I.putpalette(P);I.save("o.png")

कमांड लाइन पर एक इनपुट फ़ाइल नाम लेता है और आउटपुट को लिखता है o.png


2
आर्ग, जो मैं करने की कोशिश कर रहा हूं, उससे बहुत सरल है। +1
मार्टिन एंडर

7

गणितज्ञ 225


अपडेट :

ओपी ने फैसला किया कि यह दृष्टिकोण कंप्यूटर विज़न फ़ंक्शंस का उपयोग करता है, इसलिए यह अब चलने में नहीं है। हालाँकि मैं इसे पोस्ट करता हूँ। शायद किसी को यह रुचिकर लगे।


f@i_ := (m = MorphologicalComponents[ImageData@i];
Image@Partition[Flatten[(m)] /. 
   Append[ ReplacePart[SortBy[ComponentMeasurements[m, "Circularity"], Last], 
   {{1, 2} -> Yellow, {2, 2} -> Green, {3, 2} -> Red, {4, 2} -> Blue}], 0 -> Black], 
Dimensions[m][[2]]])

ImageData 0 और 1 के मैट्रिक्स के रूप में छवि लौटाता है।

Flatten उस मैट्रिक्स को एक सूची में परिवर्तित करता है।

Morphological Componentsपिक्सेल के 4 समूहों को पाता है और क्लस्टर के अनुसार प्रत्येक पिक्सेल के लिए एक अलग पूर्णांक, 1, 2, 3, 4 प्रदान करता है। 0 (काली) पृष्ठभूमि के लिए आरक्षित है।

ComponentMeasurements समूहों की गोलाकारता का परीक्षण करता है।

सबसे कम से कम परिपत्र हमेशा होगा: सर्कल, वर्ग, त्रिकोण और गियर।

ReplacePart प्रत्येक घटक पूर्णांक को संबंधित आरजीबी रंग के साथ बदल देता है, जो परिपत्रता प्रकार का उपयोग करता है।

Partition...Dimensions[m][[2]] पिक्सेल रंगों की सूची लेता है, और एक मैट्रिक्स को इनपुट छवि के समान आयाम देता है।

Image पिक्सेल रंगों के मैट्रिक्स को रंगीन छवि में परिवर्तित करता है।

आदानों

{f[img1],f[img2],f[img3],f[img4]}

आउटपुट


147 f@i_:=Image[#/.Append[Thread[Ordering[Last/@ComponentMeasurements[#,"Circularity"]]->{Yellow,Green,Red,Blue}],0->Black]]&@MorphologicalComponents@i
चरस

मामूली बिंदु: आपके रंगों में सही आरजीबी मूल्य नहीं हैं। मुख्य बिंदु: मुझे यकीन नहीं है कि मैं इसे कंप्यूटर विज़न लाइब्रेरी या फ़ंक्शंस का उपयोग न करने के रूप में गिनाऊंगा।
केल्विन के शौक

"परिपत्रता" यकीनन दृश्य है; मैं देखूंगा कि मैं और क्या कर सकता हूं। हालाँकि, रंग मृत हैं: {RGBColor[1, 0, 0], RGBColor[0, 1, 0], RGBColor[0, 0, 1], RGBColor[1, 1, 0]}1 पर , जहां 255 से मेल खाती है। कोई लाइब्रेरी का उपयोग नहीं किया गया।
डेविड नोव

@ केल्विन के शौकिन इस मुद्दे को कम करने के लिए लगता है कि क्या MorphologicalComponentsआपके नियमों को संतुष्ट या उल्लंघन करता है। एक बार जब यह पता चल जाता है कि प्रत्येक पिक्सेल किस क्लस्टर का है, तो यह निर्धारित करने के लिए पिक्सेल की एक कच्ची गिनती सहित कई तरीके हैं।
डेविड नोव

मैं यह कहने जा रहा हूं कि यह नियमों का उल्लंघन करता है, क्योंकि यह यकीनन एक कंप्यूटर विज़न फंक्शन है, और यह गणितज्ञ को अनुचित लाभ देता है। मैं मानता हूं कि रंग सही होना चाहिए लेकिन वे आपकी छवि में स्पष्ट रूप से दिखते हैं (लाल (255,0,22)जब मैं पेंट में जांच करता हूं)। मेरे पास गणितज्ञ नहीं है इसलिए मैं यह सुनिश्चित करने के लिए दौड़ नहीं सकता।
केल्विन के शौक

7

गणितज्ञ, 354 345 314 291 288

फिर भी गोल्फिंग को कुछ और चार्ट से छोटा किया जा सकता है, लेकिन प्रदर्शन असहनीय हो जाता है। आकृतियों की पहचान करने के लिए विविधता का उपयोग करता है:

f=(w=Position[z=ImageData@Import@#,1];r=Nearest;v@x_:=Variance@N[Norm[Mean@x-#]&/@x];Image[Plus@@(ReplacePart[0z/. 0->{0,0,0},#->r[{108,124,196,115}->List@@@{Blue,Red,Green,Yellow},v@#][[1]]]&/@Rest@NestList[(m=r[w=w~Complement~#];FixedPoint[Union@@(m[#,{8,2}]&/@#)&,{#&@@w}])&,{},4])])&

रिक्ति के साथ:

f = (w = Position[z = ImageData@Import@#, 1];
     r = Nearest; 
     v@x_ := Variance@N[Norm[Mean@x - #] & /@ x];
     Image[Plus @@ (ReplacePart[ 0 z /. 0 -> {0, 0, 0}, # -> r[{108, 124, 196, 115} -> 
                                              List @@@ {Blue, Red, Green, Yellow}, v@#][[1]]] & /@
     Rest@NestList[(m = r[w = w~ Complement~#];
                   FixedPoint[Union @@ (m[#, {8, 2}] & /@ #) &, {# & @@ w}]) &
                   , {}, 4])]) &

परिक्षण:

s = {"http://i.stack.imgur.com/Oa2O1.png", "http://i.stack.imgur.com/C6IKR.png", 
     "http://i.stack.imgur.com/YZfc6.png", "http://i.stack.imgur.com/F1ZDM.png", 
     "http://i.stack.imgur.com/chJFi.png", "http://i.stack.imgur.com/DLM3y.png"};
Partition[f /@ s, 3] // Grid

गणितज्ञ ग्राफिक्स

यहां यह पूरी तरह से अनऑर्गनाइज्ड है। बाद में स्पष्टीकरण जोड़ेंगे:

findOneZone[{universe_List, lastZone_List}] :=
 Module[{newUniverse, proximityFindFunc, seedElement},
  newUniverse = Complement[universe, lastZone];
  proximityFindFunc = Nearest@newUniverse;
  seedElement = {First@newUniverse};
  {newUniverse, FixedPoint[Union @@ (proximityFindFunc[#, {8, 2}] & /@ #) &, seedElement]}]

colorAssign[zone_List] :=
 Module[{
   vlist = {108, 124, 196, 115},
   cols = List @@@ {Blue, Red, Green, Yellow},
   centerVariance},
  centerVariance[x_List] := Variance@N[Norm[Mean@x - #] & /@ x];
  First@Nearest[vlist -> cols, centerVariance@zone]]

colorRules[zones_List] := (# -> colorAssign[#] & /@ zones)

main[urlName_String] := 
 Module[{pixels, FgPixelPositions, rawZones, zones},
  pixels = ImageData@Import@urlName;
  FgPixelPositions = Position[pixels, 1];
  (*fill and separate the regions*)
  rawZones = NestList[findOneZone[#] &, {FgPixelPositions, {}}, 4];
  zones = Rest[rawZones][[All, 2]];
  (*Identify,colorize and render*)
  Image@ReplacePart[ConstantArray[{0, 0, 0}, Dimensions@pixels], 
    colorRules[zones]]]

s = {"http://i.stack.imgur.com/Oa2O1.png"};
main /@ s

2

पायथन, 579 577 554 514 502 501 बाइट्स

प्रत्येक आकार के लिए, बाढ़ भरता है, फिर सेंट्रोइड और सबसे दूर बिंदु के बीच की दूरी की गणना करें।

फिर आकृति की वास्तविक सतह की तुलना त्रिकोण, वर्ग, डिस्क या पहिया की सतह से की जाती है, जिसका आकार समान होगा।

आयात गणित ; से जनहित याचिका छवि आयात *; , आर , _ , आई = एब्स , रेंज ( 300 ), 255 , ओपन ( sys Argv [ 1 ])। कन्वर्ट ( 'पी' ); क्यू = मैं लोड () के लिए j में आर : के लिए मैं में आर : अगर क्यू [ 

 
  मैं , जे ] == _ : 
   एक्स , वाई , एस , जेड , पी = 0 , 0 , 0 , [], [( मैं , जे )] जबकि पी : 
    एक , = n = पी pop () if not ( Q [ n ]! = _ या n in z ): 
     X + = a ; + =
   
     बी ; z + = [ एन ]; p + = [( a , b - 1 ), ( a + 1 , b ), ( a , b + 1 ), ( a - 1 , b )]; s + = 1 
   r = max ([ गणित हाइप ( एक्स / एस - x , Y / s - y ) के लिए x , y में z ]); सी = { 1 : ( एस - ( 1.4 * आर ) ** 2 ), 2 : ( एस - आर * आर / 3 ), 3 : ( एस - गणित पी * आर * आर ), 4 : ए। ( s - 2.5 * r * r )} z में p के लिए
   : 
    क्यू [ पी ] = मिनट ( सी , कुंजी = सी प्राप्त ) 
मैं putpalette ([ 0 , 0 , 0 , _ ] * 3 + [ _ , _ , 0 ]) 
मैं दिखाना ()

1

सी # 1086 बाइट्स

अभी तक रिकॉर्ड के लिए एक और फ्लडफिल-सॉल्यूशन, क्योंकि यहां कोई C # वर्जन नहीं है। Quincunx की तरह मैं खुद को साबित करना चाहता था कि मैं यह कर सकता हूं और जावा में उनके दृष्टिकोण में बहुत अंतर नहीं है।

  • यह समाधान किसी भी पुनरावृत्ति (लेकिन एक स्टैक) का उपयोग नहीं करता है क्योंकि मैं स्टैकऑवरफ्लोज़ में चलता रहा।
  • बॉर्डरपिक्सल्स का पता लगाना अगले 4 पिक्सल को देखकर आसान हो जाता है, अगर उनमें से कोई भी काला है, तो वर्तमान बॉर्डर पिक्सेल है।

यह हर इमेजफॉर्म को स्वीकार करता है।

  • पैरामीटर 1 = इनपुटपैथ
  • पैरामीटर 2 = आउटपुटपैथ

यह शायद सभी स्थैतिक सामान को हटाकर और प्रोग्राम का एक उदाहरण बनाकर कुछ सारसों को छीन लिया जा सकता है।

पठनीय संस्करण:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;

class Program
{
    static Bitmap img;
    static int w, h;
    static ISet<Point> pointsDone = new HashSet<Point>();
    static void Main(string[] a)
    {
        img = new Bitmap(a[0]);
        w = img.Width;
        h = img.Height;
        Bitmap clone = new Bitmap(w,h, PixelFormat.Format32bppArgb);
        Graphics.FromImage(clone).DrawImage(img, 0, 0, w, h);
        img = clone;




        Color[] colors = new[] { Color.Blue, Color.Red, Color.Green, Color.Yellow };

        var shapes = new List<ISet<Tuple<bool, Point>>>();
        for(int x=0;x<w;x++)
            for (int y = 0; y < h; y++)
            {
                Point p = new Point(x, y);
                if (pointsDone.Add(p) && _isWhitePixel(p))
                    shapes.Add(_detectShape(p));
            }
        int index = 0;
        foreach (var shp in shapes.OrderBy(shp => shp.Count(item => item.Item1)))
        {
            foreach (var pixel in shp)
                img.SetPixel(pixel.Item2.X, pixel.Item2.Y, colors[index]);
            index++;
        }

        img.Save(a[1]);
    }

    private static ISet<Tuple<bool, Point>> _detectShape(Point p)
    {
        var todo = new Stack<Point>(new[] { p });
        var shape = new HashSet<Tuple<bool, Point>>();
        do
        {
            p = todo.Pop();
            var isBorderPixel = false;
            foreach (var n in new[] { new Point(p.X + 1, p.Y), new Point(p.X - 1, p.Y), new Point(p.X, p.Y + 1), new Point(p.X, p.Y - 1) })
                if (_isWhitePixel(n))
                {
                    if (pointsDone.Add(n))
                        todo.Push(n);
                }
                else isBorderPixel = true; // We know we are at the border of the shape
            shape.Add(Tuple.Create(isBorderPixel, p));

        } while (todo.Count > 0);
        return shape;
    }

    static bool _isWhitePixel(Point p)
    {
        return img.GetPixel(p.X, p.Y).ToArgb() == Color.White.ToArgb();
    }
}

golfed:

using System;using System.Collections.Generic;using System.Drawing;using System.Drawing.Imaging;using System.Linq;class P{static Bitmap a;static int w,h;static ISet<Point> d=new HashSet<Point>();static void Main(string[] q){a=new Bitmap(q[0]);w=a.Width;h=a.Height;var c=new Bitmap(w,h,PixelFormat.Format32bppArgb);Graphics.FromImage(c).DrawImage(a,0,0,w,h);a=c;var e=new[]{Color.Blue,Color.Red,Color.Green,Color.Yellow};var f=new List<ISet<dynamic>>();for(int x=0;x<w;x++)for(int y=0;y<h;y++){Point p=new Point(x,y);if (d.Add(p)&&v(p))f.Add(u(p));}int i=0;foreach(var s in f.OrderBy(s=>s.Count(item=>item.b))){foreach(var x in s)a.SetPixel(x.p.X,x.p.Y,e[i]);i++;}a.Save(q[1]);}private static ISet<dynamic> u(Point p){var t=new Stack<Point>(new[]{p});var s=new HashSet<dynamic>();do{p=t.Pop();var b=false;foreach(var n in new[]{new Point(p.X+1,p.Y),new Point(p.X-1,p.Y),new Point(p.X,p.Y+1),new Point(p.X,p.Y-1)})if(v(n)){if (d.Add(n))t.Push(n);}else b=true;s.Add(new{b,p});}while (t.Count>0);return s;}static bool v(Point p){return a.GetPixel(p.X,p.Y).ToArgb()==Color.White.ToArgb();}}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.