एक छवि का औसत रंग


21

एक छवि का औसत रंग

वैज्ञानिक औसत रंग निर्धारित करने में सक्षम रहे हैं ब्रह्मांड हैं लेकिन हम एक छवि पर कितने में बाइट पा सकते हैं?

आपका कार्य

आपका इनपुट एक एकल छवि होगी जिसे आपको छवि में रंगों का औसत खोजने और हेक्स रंग-स्ट्रिंग ( #??????) को आउटपुट करने की आवश्यकता होगी । छवि निम्न में से किसी भी प्रारूप की हो सकती है

  • जेपीईजी / JFIF
    • जेपीईजी 2000
  • TIFF
  • GIF
  • बीएमपी
  • पीएनजी
  • पीएनएम
    • पीपीएम

इनपुट को छवि के URL / URI के रूप में भी लिया जा सकता है।

बिल्ड-फ़ंक्शंस जो छवि की गणना करते हैं या एक बार में नमूना लेते हैं जैसे कि ImageMeasurementsअनुमति नहीं है।

उदाहरण

परिणाम इस आधार पर थोड़ा भिन्न होगा कि आप औसत और किस रंग के मॉडल की गणना करते हैं। मैंने नीचे की छवियों के लिए RGB और LCH (HSV) मान जोड़े हैं।

नमूना 1आउटपुट: #53715FRGB, #3B7D3DLCH (HSV) भी हो सकता है


नमूना २आउटपुट: #8B7D41RGB, #96753CLCH (HSV)


हमें किस छवि प्रारूप को संभालना है? विशेष रूप से, क्या हम केवल पीपीएम को संभालने का विकल्प चुन सकते हैं?
डेनिस

क्या मेरे पास एक छोटा परीक्षण मामला हो सकता है? मेरी स्क्रिप्ट बहुत धीमी है, और जब मैं इसे बड़े मामले पर चलाऊंगा, तो मैं उस समय को बर्बाद नहीं करूंगा यदि यह गलत है। या यहां तक ​​कि सिर्फ स्क्रिप्ट के साथ आपने इसकी गणना की।
माल्टीसेन

@ मैलेटेन ने एक 240x140 उदाहरण जोड़ा है। उम्मीद है कि यह काफी छोटा है
डाउनगोलाट

क्या हमें हमेशा गोल होना चाहिए? पहले उदाहरण में 95.6..., जिसे आपने 95निर्दिष्ट आउटपुट में राउंड किया है।
डेनिस

4
PS, सैंडबॉक्स में कोई सवाल पोस्ट करने का कोई मतलब नहीं है जब तक कि आप इसे कम से कम 24 घंटे तक नहीं छोड़ेंगे , ताकि अन्य समय क्षेत्र के लोग इसे देख सकें, और वास्तविक रूप से आपको इसे 72 घंटे देने की आवश्यकता है क्योंकि हर कोई चेक नहीं करता है सैंडबॉक्स जुनूनी।
पीटर टेलर

जवाबों:


19

पायथ - 23 22 19 18 16 बाइट्स

सभी चैनलों को प्राप्त करने का प्रस्ताव करता है, फिर प्रत्येक को समेटता है, विभाजित करता है और हेक्सिज़ करता है। समापन और पूर्वसर्ग द्वारा समाप्त होता है a #

+\#sm.H/sdldCs'z

स्टड से एक छवि फ़ाइल नाम (किसी भी प्रकार) लेता है और स्टडआउट को आउटपुट करता है। बहुत धीमी है

+               String concat
 \#             "#"
 s              String concat all channels
 m              Map
  .H            Hex string
    /  ld       Divided by length of channel
     sd         Sum of channel
  C             Transpose to separate into channels
   s            Concatenate all rows
    'z          Read image with filename input

नमूना चला

>>>pyth avg.pyth 
V5VAR.jpg
#8b7d41

आप छवि प्रकार निर्दिष्ट करना चाह सकते हैं, यदि कोई हो।
isaacg

1
@ आइसाकग अच्छी बात। यह कुछ भी लेता है।
माल्टीसेन

यह कुछ भी कैसे लेता है, क्या यह jpeg को बिटमैप में डिकोड करता है?
एलेक टीले

3
@AlecTeal दस्तावेज़ीकरण के अनुसार पाइथ यह जाँचता है कि क्या फ़ाइल एक छवि है और स्वचालित रूप से इसे बिटमैप में परिवर्तित करती है। GitHub रिपॉजिटरी की खोज से ऐसा लगता है कि यह PILचित्रों को संभालने के लिए लाइब्रेरी का उपयोग करता है । सटीक स्रोत के लिए यहां देखें ।
बकुरीउ

@ बकुरीउ - मैंने इस जवाब को नहीं उठाया क्योंकि मुझे पता नहीं था कि पाइथ ने कैसे छवियों को संभाला है, इसलिए यह मुझे थोड़ा गड़बड़ लग रहा था ... लेकिन अब जब आप वहां जानकारी प्रदान करते हैं, तो यह मेरा वोट हो जाता है। स्पष्टीकरण के लिए धन्यवाद!
रायरेंग - मोनिका जूल 22'15

22

बैश, 46 बाइट्स

ImageMagick एक पिक्सेल के लिए छवि को स्केल करता है जिसमें छवि में रंगों का औसत होता है फिर इसे टेक्स्ट के रूप में आउटपुट करता है।

convert $1 -scale 1x1\! txt:-|egrep -o '#\w+'

4
यह स्मार्ट है! +1
माल्टीसेन जूल

10

MATLAB - 68 बाइट्स

जिस छवि को आप लोड करना चाहते हैं उसे चुनने के लिए GUI को खोलने के लिए imreadसंयुक्त के साथ छवि को पढ़ा जाता uigetfileहै। इस कोड के साथ धारणा यह है कि सभी छवियां RGB हैं, और औसत रंग की गणना करने के लिए, हम प्रत्येक चैनल को व्यक्तिगत रूप से विभाजित करते हैं। एक चैनल में जितने तत्व हैं, उतने ही हैं, जो RGB इमेज में पिक्सल की कुल संख्या है ( ) 3 से विभाजित। क्योंकि औसत संभवतः फ्लोटिंग पॉइंट वैल्यू उत्पन्न कर सकता है, नंबर को शून्य की ओर गोल करने के लिए कॉल की आवश्यकता होती है। । हेक्साडेसिमल स्वरूपण स्ट्रिंग ( ) के साथ संयुक्त औसत में प्रत्येक पूर्णांक मान को अपने हेक्स समकक्ष में प्रिंट करने के लिए उपयोग किया जाता है। हालांकि, क्या यह सुनिश्चित करना है कि एक अतिरिक्त 0 को बाईं ओर रखा गया है, किसी भी चैनल के लिए औसत मूल्य 16 से कम होना चाहिएnumel(I)fixsprintf%x02 *)

I=imread(uigetfile);
['#' sprintf('%02x',fix(sum(sum(I))*3/numel(I)))]

नमूना चलाता है

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

पहली छवि

>> I=imread('http://i.stack.imgur.com/dkShg.jpg');
>> ['#' sprintf('%02x',fix(sum(sum(I))*3/numel(I)))]

ans =

#53715f

दूसरी छवि

>> I=imread('http://i.stack.imgur.com/V5VAR.jpg');
>> ['#' sprintf('%02x',fix(sum(sum(I))*3/numel(I)))]

ans =

#8b7d41

* नोट: यह MATLAB और ऑक्टेव चैट रूम पर StackOverflow उपयोगकर्ताओं द्वारा किया गया एक सहयोगी प्रयास था ।


7

सीजेएम, 27 बाइट्स

'#[q~]5>3/_:.+\,f/"%02X"fe%

यह STDIN से एक PPM छवि पढ़ता है।

CJam में कोई अंतर्निहित छवि प्रसंस्करण नहीं है, इसलिए यह कोड पूर्ण 24-बिट पैलेट (अधिकतम मूल्य 255) और कोई टिप्पणी नहीं के साथ एक ASCII पोर्टेबल PixMap (जादू नंबर P3) की उम्मीद करता है।

परीक्षण चालन

$ cjam avg.cjam < dkShg.ppm 
#53715F

यह काम किस प्रकार करता है

'#     e# Push that character.
[q~]   e# Evaluate the input and collect the results in an array.
5>     e# Discard the first first results (Pi, 3, width, height, range).
3/     e# Split into chunks of length 3 (RGB).
_:.+   e# Push a copy and add across the columns (RGB).
\,f/   e# Divide each sum by the length of the array (number of pixels).
"%02X" e# Push that format string (hexadecimal integer, zero-pad to two digits).
fe%    e# Format each integer, using the format string.

7

एचटीएमएल 5 + जावास्क्रिप्ट (ईएस 6), 335 बाइट्स

यह जीतने वाला नहीं है, लेकिन मुझे इसे वैसे भी करने में मज़ा आया।

HTML5 कैनवास एपीआई का उपयोग करता है । इनपुट एक कोर-सक्षम छवि का एक URL है ।

f=(u,i=new Image)=>{i.crossOrigin='';i.src=u;i.onload=e=>{x=(c=document.createElement('canvas')).getContext('2d');a=w=c.width=i.width;a*=h=c.height=i.height;x.drawImage(i,0,0);for(d=x.getImageData(m=0,0,w,h).data,r=[0,0,0];m<d.length;m+=4){r[0]+=d[m];r[1]+=d[m+1];r[2]+=d[m+2]}console.log('#'+r.map(v=>(~~(v/a)).toString(16)).join``)}}

डेमो

जैसा कि यह ES6 है, यह वर्तमान में केवल फ़ायरफ़ॉक्स और एज में काम करता है।

f = (u,i = new Image) => {
  i.crossOrigin = '';
  i.src = u;
  i.onload = e => {
    x = (c = document.createElement('canvas')).getContext('2d');
    a = w = c.width = i.width;
    a *= h = c.height = i.height;
    x.drawImage(i, 0, 0);
    for (d = x.getImageData(m = 0, 0, w, h).data, r = [0, 0, 0]; m < d.length; m += 4) {
      r[0] += d[m]
      r[1] += d[m + 1];
      r[2] += d[m + 2];
    }
    console.log('#' + r.map(v => (~~(v/a)).toString(16)).join``)
  }
}

// Snippet stuff
console.log = x => document.body.innerHTML += x + '<br>';

f('http://crossorigin.me/https://i.stack.imgur.com/dkShg.jpg');

f('http://crossorigin.me/https://i.stack.imgur.com/V5VAR.jpg');


3
अरे, मुझे यह पसंद है कि यह सीधे आपके जवाब में चलने योग्य है क्योंकि यह HTML + JS :) +1 है।
रायरेंग - मोनिका जूल

आप को बदल नहीं सकता new Imageके साथ Image()?
इस्माइल मिगुएल

@ इस्माईल मिगुएलTypeError: Constructor Image requires 'new'
rink.attenders.6

बकवास। लेकिन आप बना सकते हैंW='width' और H='height'उपयोग और उपयोगi[H] याi[W]
Ismael Miguel

1
@IsmaelMiguel जो अधिक वर्णों का उपयोग करता है
rink.attenders.6

6

पायथन [3] + साइंसपी, १४४ १३३ १२१

पिक्सेल डेटा को लोड करता है, प्रत्येक चैनल के लिए रकम, आकार *, स्वरूपों द्वारा विभाजित करता है। मान शून्य की ओर गोल होते हैं।

* आकार = चौड़ाई * ऊंचाई * चैनल, इस प्रकार 3 से गुणा किया जाता है

from scipy import misc,sum
i=misc.imread(input())
print('#'+(3*'{:2x}').format(*sum(i.astype(int),axis=(0,1))*3//i.size))

1
input()रास्ता लेने के लिए उपयोग क्यों नहीं ? यह आपको 20 बाइट्स बचाएगा।
काडे

धन्यवाद! मैं हालांकि 11 बाइट्स बचाने में कामयाब रहा हूं।
तुरंग ऊल

आप केवल एक आयात की जरूरत है import scipy। बदलें m.imreadकरने के लिए misc.imread
केड

, विविध आयात किए बिना काम नहीं करता है NameError: name 'misc' is not defined। कोशिश की from scipy import*, काम भी नहीं करता है।
ट्रांग ओउल

2
@TrangOul के बारे में क्या from scipy import sum, misc as m? जब आप राशि का उपयोग करते हैं तब आप बचत करते हैं, तब।
मैट्सजॉयस

3

आर, 90 बाइट्स

rgb(matrix(apply(png::readPNG(scan(,"")),3,function(x)sum(x*255)%/%length(x)),nc=3),m=255)

पीएनजी फ़ाइल का पथ STDIN से पढ़ा जाता है। पैकेज pngस्थापित करने की आवश्यकता है।

क्रमशः:

#Reads path from stdin and feeds it to function readPNG from package png
p = png::readPNG(scan(,""))
#The result is a 3d matrix (1 layer for each color channel) filled with [0,1] values
#So next step, we compute the mean on each layer using apply(X,3,FUN)
#after moving the value to range [0,255] and keeping it as an integer.
a = apply(p,3,function(x)sum(x*255)%/%length(x))
#The result is then moved to a matrix of 3 columns:
m = matrix(a, nc=3)
#Which we feed to function rgb, while specifying that we're working on range [0,255]
rgb(m, m=255)

# Example:
rgb(matrix(apply(png::readPNG(scan(,"")),3,function(x)sum(x*255)%/%length(x)),nc=3),m=255)
# 1: ~/Desktop/dkShg.png
# 2: 
# Read 1 item
# [1] "#53715F"

2

सी, 259 बाइट्स

कोई टिप्पणी नहीं के साथ एक पीपीएम फ़ाइल लेता है ।

double*f,r,g,b;x,y,z,i;char*s="%d %d %d";main(a,_){(a-2)?(feof(f)?0:(fscanf(f,s,&x,&y,&z),r+=(x-r)/i,g+=(y-g)/i,b+=(z-b)/i++,main(0,0))):(f=fopen(((char**)_)[1],"r"),fscanf(f,"%*s%*d%*d%*d"),r=g=b=0.,i=1,main(0,0),printf(s,(int)r,(int)g,(int)b),fclose(f));}

प्रक्रिया

प्रारंभिक कोड:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    FILE *f = fopen(argv[1],"r");
    int w,h,d,x,y,z,i;
    double r,g,b;
    fscanf(f,"%*s %d %d %d",&w,&h,&d);//get width, height, depth, ignore P6
    r = g = b = 0.0; //zero r, g, and b totals
    for (i=1; i<=w*h; ++i) {
        fscanf(f,"%d %d %d",&x,&y,&z);//get next pixel
        r+=(x-r)/i;//update averages
        g+=(y-g)/i;
        b+=(z-b)/i;
    }
    printf("%d %d %d",(int)r,(int)g,(int)b);//print result
    fclose(f);
    return 0;
}

चर ट्रिम करें और लूप निकालें:

double r,g,b;
FILE *f;
int i;
int main(int argc, char *argv[])
{
    if (argc==2) { // {./me} {file.ppm}
        f = fopen(argv[1],"r");
        fscanf(f,"%*s%*d%*d%*d");//drop info
        r = g = b = 0.0;
        i = 1;
        main(0,0);//begin load loop
        printf("%d %d %d",(int)r,(int)g,(int)b);
        fclose(f)
    } else {
        if (feof(f)) return 0;
        fscanf(f,"%d%d%d",&x,&y,&z);
        r+=(x-r)/i;
        g+=(y-g)/i;
        b+=(z-b)/i;
        i++;
        main(0,0);
    }
    return 0;
}

वहाँ से मैंने विभिन्न विवरणों को एक सिंगल रिटर्न स्टेटमेंट में संयोजित किया। इसे हटा दिया और किसी भी अन्य बाहरी प्रकार की जानकारी, नाम बदल चर, और काट दिया।


2

कोबरा - 371

@ref 'System.Numerics'
use System.Drawing
use System.Numerics
class P
    def main
        i,d=Bitmap(Console.readLine?''),BigInteger
        r,g,b,c=d(),d(),d(),d()
        for x in i.width,for y in i.height,r,g,b,c=for n in 4 get BigInteger.add([r,g,b,c][n],d([(p=i.getPixel(x,y)).r,p.g,p.b,1][n]))
        print'#'+(for k in[r,g,b]get Convert.toString(BigInteger.divide(k,c)to int,16)).join('')

2

जावा, 449 447 446 430 426 बाइट्स

import java.awt.*;interface A{static void main(String[]a)throws Exception{java.awt.image.BufferedImage i=javax.imageio.ImageIO.read(new java.io.File(new java.util.Scanner(System.in).nextLine()));int r=0,g=0,b=0,k=0,x,y;for(x=0;x<i.getWidth();x++)for(y=0;y<i.getHeight();k++){Color c=new Color(i.getRGB(x,y++));r+=c.getRed();g+=c.getGreen();b+=c.getBlue();}System.out.printf("#%06X",0xFFFFFF&new Color(r/k,g/k,b/k).getRGB());}}

चाल के लिए स्टैक ओवरफ्लो पर इस जवाब के लिए धन्यवाद String.format

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.