আমি কীভাবে কোনও আরজিবি চিত্রকে পাইথনের গ্রেস্কেল রূপান্তর করতে পারি?


205

আমি matplotlibকোনও আরজিবি ছবিতে পড়তে এবং এটিকে গ্রেস্কেলে রূপান্তর করতে ব্যবহার করার চেষ্টা করছি ।

মাতলাব আমি এটি ব্যবহার:

img = rgb2gray(imread('image.png'));

ইন matplotlib টিউটোরিয়াল তারা তা আবরণ না। তারা কেবল ছবিতে পড়ে

import matplotlib.image as mpimg
img = mpimg.imread('image.png')

এবং তারপরে তারা অ্যারে টুকরো টুকরো করে, তবে আরজিবিকে আমি যা বুঝি তা থেকে গ্রেস্কেলের রূপান্তরিত করার মতো জিনিস নয়।

lum_img = img[:,:,0]

আরজিবি থেকে ধূসরতে রূপান্তরিত করার জন্য নিম্পি বা ম্যাটপ্ল্লোলিবের অন্তর্নির্মিত ফাংশন নেই বলে বিশ্বাস করা আমার পক্ষে কঠিন। ইমেজ প্রসেসিংয়ে এটি কি সাধারণ কাজ নয়?

আমি একটি খুব সাধারণ ফাংশন লিখেছি যা imread5 মিনিটের মধ্যে আমদানি করা চিত্রটির সাথে কাজ করে । এটি মারাত্মকভাবে অদক্ষ, তবে সে কারণেই আমি অন্তর্নির্মিত কোনও পেশাদার বাস্তবায়ন আশা করছিলাম।

সেবাস্তিয়ান আমার ফাংশনটির উন্নতি করেছে, তবে আমি এখনও বিল্ট-ইনটি খুঁজে পেতে আশা করছি।

মতলব (এনটিএসসি / পাল) বাস্তবায়ন:

import numpy as np

def rgb2gray(rgb):

    r, g, b = rgb[:,:,0], rgb[:,:,1], rgb[:,:,2]
    gray = 0.2989 * r + 0.5870 * g + 0.1140 * b

    return gray

2
মনে রাখবেন আপনি কেবল আপনার rgb2gray ফাংশন হিসাবে একই জিনিস লিখতে পারেন: gray = np.mean(rgb, -1)। সম্ভবত rgb[...,:3]সেখানে যদি এটি আরজিবা হয়।
seberg

হুঁ, ভাল gray = np.mean(rgb, -1)কাজ করে। ধন্যবাদ। এটি ব্যবহার না করার কোনও কারণ আছে কি? পরিবর্তে আমি নীচের উত্তরগুলিতে সমাধানগুলি কেন ব্যবহার করব?
waspinator

6
গ্রেস্কেল পৃষ্ঠা উইকিপিডিয়া বলছে ধূসরস্কেলে আরজিবি রূপান্তর পদ্ধতি অনন্য নয়, কিন্তু একটি সাধারণভাবে ব্যবহৃত ঔজ্জ্বল্য উপর ভিত্তি করে সূত্র দেয়। এটির তুলনায় একেবারে আলাদা np.mean(rgb, -1)
আনটবু

2
সুতরাং আমি অনুমান করি যে আমি মতলবের সংস্করণ চাই ? 0.2989 * R + 0.5870 * G + 0.1140 * B আমি ধরে নিচ্ছি যে এটি করার এটি আদর্শ উপায় way
ভিজিপেনেটর

উত্তর:


303

বালিশ দিয়ে এটি কীভাবে করবেন :

from PIL import Image
img = Image.open('image.png').convert('LA')
img.save('greyscale.png')

ম্যাটপ্ল্লিটিব এবং সূত্র ব্যবহার করে

Y' = 0.2989 R + 0.5870 G + 0.1140 B 

আপনি করতে পারেন:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

def rgb2gray(rgb):
    return np.dot(rgb[...,:3], [0.2989, 0.5870, 0.1140])

img = mpimg.imread('image.png')     
gray = rgb2gray(img)    
plt.imshow(gray, cmap=plt.get_cmap('gray'), vmin=0, vmax=1)
plt.show()

3
যদি তাকে matplotlibঅন্য কোনও কারণে ব্যবহার করতে হয় তবে তার জন্য বিল্টিনটি colorsys.rgb_to_yiq()কেবল লুমা চ্যানেলটি পেতে আরও একটি স্লাইস রূপান্তর করতে সক্ষম হওয়া উচিত ।
সিলাস রায়

34
কেন .convert('LA')? কেন না .convert('gray')? অযথা ক্রিপ্টিক বলে মনে হচ্ছে। PIL ডকুমেন্টেশন রূপান্তর ফাংশন জন্য 'লা' সম্পর্কে কিছু উল্লেখ নেই।
ভিজিপেনেটর

25
পিআইএল ব্যবহার করে cannot write mode LA as JPEG
:,

6
এটি হওয়া img = Image.open('image.png').convert('LA')দরকারimg = Image.open('image.png').convert('L')
nviens

12
@ ব্লু পাইথন: LAমোডে আলোকিততা (উজ্জ্বলতা) এবং আলফা রয়েছে। আপনি যদি LAমোড ব্যবহার করেন তবে greyscale.pngসংরক্ষণিত আলফা চ্যানেল সহ একটি আরজিবিএ চিত্র হবে image.png। আপনি যদি Lমোড ব্যবহার করেন তবে greyscale.pngএটি একটি আরজিবি চিত্র হবে (কোনও আলফা ছাড়াই)।
আনটবু

69

আপনি সাইকিট-ইমেজও ব্যবহার করতে পারেন যা কোনও চিত্রকে ndarrayযেমন রূপান্তর করতে কিছু ফাংশন সরবরাহ করে rgb2gray

from skimage import color
from skimage import io

img = color.rgb2gray(io.imread('image.png'))

নোটস : এই রূপান্তরটিতে ব্যবহৃত ওজনগুলি সমসাময়িক সিআরটি ফসফোর্সের জন্য ক্যালিব্রেট করা হয়: Y = 0.2125 আর + 0.7154 জি + 0.0721 বি

বিকল্পভাবে, আপনি গ্রেস্কেল এ চিত্রটি দ্বারা পড়তে পারেন:

from skimage import io
img = io.imread('image.png', as_gray=True)

এটা কি স্বাভাবিক যে আমি 0 <মান <1 পাচ্ছি? আসল ধূসর স্কেল পেতে কি আমি তাদের 255 দিয়ে গুণ করব?
স্যাম

আমার উদ্দেশ্য জিএলসিএম বৈশিষ্ট্যগুলি (গ্রাইক্রোপপস)
স্যাম

Io.imread এর জন্য দ্রষ্টব্য: "as_grey" "as_gray" এর পক্ষে অবমূল্যায়ন করা হয়েছে। একই ব্যবহার, আমেরিকানাইজড বানান spe :)
হ্যালোজেন

1
আমি বিশ্বাস করি এটি হ'ল প্রশ্নের সর্বাধিক দরকারী উত্তর, এর আউটপুট ম্যাটপ্ল্লোলিব এবং নম্পির সাথেও সামঞ্জস্যপূর্ণ।
Mert Beşiktepe

আমি রঙের অবজেক্টটি ব্যবহার করছি তবে আমার চিত্রটি এখন ধূসর (কালো এবং সাদা) রঙের নয়। আমাকে পাইপ্লট.আইমশো () cmapas হিসাবে ব্যবহার করতে হবে gray' then only the image is shown as gray in ? কোন চিন্তা ? আমি কোথায় ভুল করছি?
গদাধারীগীক

63

প্রস্তাবিত তিনটি পদ্ধতির তিনটি 1000 আরজিবিএ পিএনজি চিত্র (224 x 256 পিক্সেল) সহ পাইর জন্য উবুন্টু 16.04 এলটিএসে (এসএসডি সহ জিয়ান ই 5 2670) চলার জন্য পরীক্ষা করা হয়েছিল।

রান করার গড় সময়

pil : 1.037 সেকেন্ড

scipy: 1.040 সেকেন্ড

sk : 2.120 সেকেন্ড

পিআইএল এবং সায়পি একরকম numpyঅ্যারে দিয়েছেন (0 থেকে 255 অবধি)। স্কাইমেজ 0 থেকে 1 পর্যন্ত অ্যারে দেয় addition এছাড়াও রঙগুলি কিছুটা আলাদা রূপান্তরিত হয়, CUB-200 ডেটাसेट থেকে উদাহরণ দেখুন

SkImage: SkImage

PIL : PIL

SciPy : SciPy

Original: মূল

Diff : এখানে চিত্র বর্ণনা লিখুন

কোড

  1. কর্মক্ষমতা

    run_times = dict(sk=list(), pil=list(), scipy=list())
    for t in range(100):
        start_time = time.time()
        for i in range(1000):
            z = random.choice(filenames_png)
            img = skimage.color.rgb2gray(skimage.io.imread(z))
        run_times['sk'].append(time.time() - start_time)

    start_time = time.time()
    for i in range(1000):
        z = random.choice(filenames_png)
        img = np.array(Image.open(z).convert('L'))
    run_times['pil'].append(time.time() - start_time)
    
    start_time = time.time()
    for i in range(1000):
        z = random.choice(filenames_png)
        img = scipy.ndimage.imread(z, mode='L')
    run_times['scipy'].append(time.time() - start_time)
    

    for k, v in run_times.items(): print('{:5}: {:0.3f} seconds'.format(k, sum(v) / len(v)))

  2. আউটপুট
    z = 'Cardinal_0007_3025810472.jpg'
    img1 = skimage.color.rgb2gray(skimage.io.imread(z)) * 255
    IPython.display.display(PIL.Image.fromarray(img1).convert('RGB'))
    img2 = np.array(Image.open(z).convert('L'))
    IPython.display.display(PIL.Image.fromarray(img2))
    img3 = scipy.ndimage.imread(z, mode='L')
    IPython.display.display(PIL.Image.fromarray(img3))
  3. তুলনা
    img_diff = np.ndarray(shape=img1.shape, dtype='float32')
    img_diff.fill(128)
    img_diff += (img1 - img3)
    img_diff -= img_diff.min()
    img_diff *= (255/img_diff.max())
    IPython.display.display(PIL.Image.fromarray(img_diff).convert('RGB'))
  4. আমদানি
    import skimage.color
    import skimage.io
    import random
    import time
    from PIL import Image
    import numpy as np
    import scipy.ndimage
    import IPython.display
  5. সংস্করণ
    skimage.version
    0.13.0
    scipy.version
    0.19.1
    np.version
    1.13.1

6
সাইপাইয়ের চিত্র I / O আক্ষরিকভাবে পিআইএল / বালিশ। অতএব, স্কাইপি পরীক্ষা করে দক্ষতার সাথে পিআইএল / বালিশকে স্নিপাইয়ের মোড়ক ফাংশনগুলি দ্বারা প্রবর্তিত তুচ্ছ ওভারহেডের সাথে কার্যকরভাবে পরীক্ষা করে নিচ্ছে। এটি সায়পাই (যা করে ) এর জন্য ওপেনসিভি (যা পিআইএল / বালিশের উপার্জন করে না ) প্রতিস্থাপন করার জন্য আরও অনেক উপকারী হত । তবুও, উত্সর্গীকৃত বেঞ্চমার্কিংয়ের জন্য ধন্যবাদ! সাইকিট দ্বারা আরোপিত বিবেচনাযোগ্য ধীরতা মনোরম ... এবং ভয়াবহ।
সিসিল কারি

ওপেনসিভির ধারণার জন্য @ সিসিল কুরিরি ধন্যবাদ! আমি যখন কিছু ফ্রি সময় পাই তখন আমি এটি যুক্ত করব।
ম্যাক্সিমিলিয়ান পিটারস

সম্মত! আমি যে উত্তরটি খুঁজছিলাম তা নয়, তবে খুব আকর্ষণীয় :)
সিরিল এন।

29

আপনি শুরু থেকে সর্বদা imreadওপেনসিভি থেকে গ্রিস্কেল হিসাবে চিত্র ফাইলটি পড়তে পারেন :

img = cv2.imread('messi5.jpg', 0)

তদতিরিক্ত, আপনি যদি আরজিবি হিসাবে চিত্রটি পড়তে চান তবে কিছু প্রক্রিয়াজাত করুন এবং তারপরে গ্রে স্কেলে রূপান্তর করুন যা আপনি cvtcolorওপেনসিভি থেকে ব্যবহার করতে পারেন :

gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

6
Ftr: 0পতাকা হয় cv2.CV_LOAD_IMAGE_GRAYSCALE
dtk

24

দ্রুত এবং বর্তমান উপায় বালিশটি ব্যবহার করা, এর মাধ্যমে ইনস্টল করা pip install Pillow

কোডটি তখন:

from PIL import Image
img = Image.open('input_file.jpg').convert('L')
img.save('output_file.jpg')

3
মনে রাখবেন, আপনি যদি উপরের উদাহরণের মতো আপনার পদ্ধতিগুলি শৃঙ্খলাবদ্ধ না করে থাকেন convertতবে চিত্রটির রূপান্তরিত অনুলিপি প্রদান করুন
ম্যাট

32 বিট PNG জন্য কাজ, মান হবে না বাতাবদ্ধ করতে 255
অ্যান্ড্রু Matuk

11

টিউটোরিয়ালটি প্রতারণা করছে কারণ এটি আরজিবিতে এনকোড করা গ্রেস্কেল চিত্রটি দিয়ে শুরু হচ্ছে, সুতরাং তারা কেবল একটি একক রঙের চ্যানেল কে টুকরো টুকরো করে কাটছে এবং এটিকে গ্রেস্কেল হিসাবে বিবেচনা করছে। আপনার যে প্রাথমিক পদক্ষেপগুলি করা দরকার তা হ'ল আরজিবি কালারস্পেস থেকে কালারস্পেসে রূপান্তর করা যা লুমা / ক্রোমা মডেলটির সান্নিধ্যযুক্ত কিছু যেমন এনইউভি / ওয়াইআইকিউ বা এইচএসএল / এইচএসভির সাথে এনকোড থাকে, তারপরে লুমার মতো চ্যানেলটি কেটে ফেলে সেই হিসাবে ব্যবহার করা হয় আপনার গ্রেস্কেল চিত্র। matplotlibYUV / YIQ তে রূপান্তর করার কোনও ব্যবস্থা সরবরাহ করে না বলে মনে হয় তবে এটি আপনাকে এইচএসভিতে রূপান্তর করতে দেয়।

matplotlib.colors.rgb_to_hsv(img)আপনার গ্রেস্কেল এর জন্য অ্যারে থেকে শেষ মান (ভি) কে টুকরো টুকরো করে ব্যবহার করার চেষ্টা করুন । এটি লুমা মান হিসাবে একেবারে সমান নয়, তবে এর অর্থ আপনি এটি সব কিছু করতে পারেনmatplotlib

পটভূমি:

বিকল্পভাবে, আপনি পিআইএল বা বিল্টিন ব্যবহার করে colorsys.rgb_to_yiq()সত্যিকারের লুমা মান সহ রঙিনস্পেসে রূপান্তর করতে পারেন। আপনি সমস্ত জায়গায় যেতে পারেন এবং আপনার নিজের লুমা-কেবল রূপান্তরকারীটি রোল করতে পারেন, যদিও এটি সম্ভবত ওভারকিল।


9

এই সূত্রটি ব্যবহার করে

Y' = 0.299 R + 0.587 G + 0.114 B 

আমরা করতে পারি

import imageio
import numpy as np
import matplotlib.pyplot as plt

pic = imageio.imread('(image)')
gray = lambda rgb : np.dot(rgb[... , :3] , [0.299 , 0.587, 0.114]) 
gray = gray(pic)  
plt.imshow(gray, cmap = plt.get_cmap(name = 'gray'))

যাইহোক, জিম্প রঙকে গ্রেস্কেল ইমেজ সফ্টওয়্যারে রূপান্তরিত করার জন্য কার্যটি করতে তিনটি অ্যালগরিদম রয়েছে।


8

আপনি যদি ইতিমধ্যে NumPy / SciPy ব্যবহার করেন তবে আপনি পাশাপাশি ব্যবহার করতে পারেন :

scipy.ndimage.imread(file_name, mode='L')


5
উভয় scipy.ndimage.imread()এবং scipy.misc.imread()করছে আনুষ্ঠানিকভাবে অবচিত SciPy 1.0.0 এবং করা হবে স্থায়ীভাবে মুছে ফেলা SciPy 1.2.0 হবে। যদিও সাইকপাইয়ের ডকুমেন্টেশনগুলি imageio.imread()উপযুক্ত প্রতিস্থাপন হিসাবে প্রস্তাব দিচ্ছে , এই ফাংশনটির এপিআই অযৌক্তিকতার দিক থেকে খালি হাড়। এটি গ্রেস্কেল রূপান্তরকরণের জন্য কোনও সমর্থন সরবরাহ করে না এবং এটি আমাদের সহ অনেকগুলি অ্যাপ্লিকেশনের জন্য অনুপযুক্ত। </sigh>
সিসিল কারি

5
@ সিসিলকিউরি, আপনি কীভাবে রঙিন চিত্রকে ধূসর আকারে রূপান্তর করবেন?
0x90

5

আপনি করতে পারেন:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

def rgb_to_gray(img):
        grayImage = np.zeros(img.shape)
        R = np.array(img[:, :, 0])
        G = np.array(img[:, :, 1])
        B = np.array(img[:, :, 2])

        R = (R *.299)
        G = (G *.587)
        B = (B *.114)

        Avg = (R+G+B)
        grayImage = img

        for i in range(3):
           grayImage[:,:,i] = Avg

        return grayImage       

image = mpimg.imread("your_image.png")   
grayImage = rgb_to_gray(image)  
plt.imshow(grayImage)
plt.show()

5

ইমজি। কনভার্ট () ব্যবহার করুন, "এল", "আরজিবি" এবং "সিএমওয়াইকে" সমর্থন করে। মোড

import numpy as np
from PIL import Image

img = Image.open("IMG/center_2018_02_03_00_34_32_784.jpg")
img.convert('L')

print np.array(img)

আউটপুট:

[[135 123 134 ...,  30   3  14]
 [137 130 137 ...,   9  20  13]
 [170 177 183 ...,  14  10 250]
 ..., 
 [112  99  91 ...,  90  88  80]
 [ 95 103 111 ..., 102  85 103]
 [112  96  86 ..., 182 148 114]]

1
5 ম লাইন হওয়া উচিত img = img.convert('L')?
অ্যালান রুইন

3

ইতিমধ্যে লোড হওয়া চিত্রটিকে গ্রেস্কেলে রূপান্তর করার উপায় অনুসন্ধান করে আমি গুগলের মাধ্যমে এই প্রশ্নে এসেছি।

এখানে সায়পাই দিয়ে এটি করার একটি উপায়:

import scipy.misc
import scipy.ndimage

# Load an example image
# Use scipy.ndimage.imread(file_name, mode='L') if you have your own
img = scipy.misc.face()

# Convert the image
R = img[:, :, 0]
G = img[:, :, 1]
B = img[:, :, 2]
img_gray = R * 299. / 1000 + G * 587. / 1000 + B * 114. / 1000

# Show the image
scipy.misc.imshow(img_gray)

1
খুশী হলাম। আমি কেবল একটি সংক্ষিপ্ত সমাধানটি নোট করতে চাইimg_gray = numpy.average(img, weights=[0.299, 0.587, 0.114], axis=2)
আকাওয়াল

আকভাল জেনে ভাল লাগল, ধন্যবাদ! আপনার শর্টকাটটি দ্রুত কিনা আপনি কি জানেন? যদি তা না হয় তবে আমি আমার রাখব কারণ এটি বোঝা সহজ।
মার্টিন থোমা

আমি এটি সময় পাই নি, আমার অন্ত্র অনুভূতি numpy.averageকিছুটা দ্রুত কিন্তু বাস্তবিকভাবে আলাদা নয়। আপনার সমাধানটি পরিষ্কার এবং আর, জি, বি সম্পর্কিত প্রাসঙ্গিক তথ্য রয়েছে, তাই আমি এটি রাখব। আমার মন্তব্যটি অতিরিক্ত বিকল্প ছিল, প্রতিস্থাপন নয়।
আকাওয়াল

উভয় scipy.ndimage.imread()এবং scipy.misc.imread()করছে আনুষ্ঠানিকভাবে অবচিত SciPy 1.0.0 এবং করা হবে স্থায়ীভাবে মুছে ফেলা SciPy 1.2.0 হবে। আপনি সম্ভবত ঠিক বালিশ এর builtin গ্রেস্কেল রূপান্তর সমর্থন ব্যবহার করবেন (Ala চান unutbu এর উত্তর , পরিবর্তে)।
সিসিল কারি

-3
image=myCamera.getImage().crop(xx,xx,xx,xx).scale(xx,xx).greyscale()

আপনি greyscale()রূপান্তর জন্য সরাসরি ব্যবহার করতে পারেন ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.