Numpy ، PIL إضافة صورة
-
22-08-2019 - |
سؤال
أحاول إضافة صورتين معًا باستخدام Numpy و Pil. الطريقة التي سأفعل بها هذا ماتلاب سيكون شيئًا مثل:
>> M1 = imread('_1.jpg');
>> M2 = imread('_2.jpg');
>> resM = M1 + M2;
>> imwrite(resM, 'res.jpg');
أحصل على شيء مثل هذا:
alt text http://www.deadlink.cc/matlab.jpg
باستخدام برنامج التركيب وإضافة الصور ، يبدو أن نتيجة MATLAB صحيحة.
في بيثون أحاول أن أفعل نفس الشيء مثل هذا:
from PIL import Image
from numpy import *
im1 = Image.open('/Users/rem7/Desktop/_1.jpg')
im2 = Image.open('/Users/rem7/Desktop/_2.jpg')
im1arr = asarray(im1)
im2arr = asarray(im2)
addition = im1arr + im2arr
resultImage = Image.fromarray(addition)
resultImage.save('/Users/rem7/Desktop/a.jpg')
وأحصل على شيء مثل هذا:
alt text http://www.deadlink.cc/python.jpg
لماذا أحصل على كل هذه الألوان غير التقليدية؟ حاولت أيضا استخدام ImageMath.eval("a+b", a=im1, b=im2)
, ، لكنني أحصل على خطأ حول RGB غير مدعوم.
رأيت أيضًا أن هناك Image.blend()
ولكن هذا يتطلب ألفا.
ما هي أفضل طريقة لتحقيق ما أبحث عنه؟
صور المصدر (تمت إزالة الصور):
alt text http://www.deadlink.cc/_1.jpg alt text http://www.deadlink.cc/_2.jpg
Humm ، حسنًا ، لقد أضفت الصور المصدر باستخدام أيقونة إضافة صورة وتظهر عند تحرير المنشور ، لكن لسبب ما لا تظهر الصور في المنشور.
(تمت إزالة الصور) 2013 05 09
المحلول
كما اقترح الجميع بالفعل ، فإن الألوان الغريبة التي تراقبها هي الفائض. وكما تشير في تعليق على إجابة شنادير أنت لا يزال الحصول على الفائض إذا أضفت صورك مثل هذا:
addition=(im1arr+im2arr)/2
سبب هذا الفائض هو أن صفائف numpy الخاصة بك (im1arr im2arr) هي من uint8 اكتب (أي 8 بت). هذا يعني أن كل عنصر من عناصر الصفيف يمكن أن يحتفظ فقط بقيم تصل إلى 255 ، لذلك عندما يتجاوز مجموعك 255 ، فإنه يحلق حوالي 0:
>>>array([255,10,100],dtype='uint8') + array([1,10,160],dtype='uint8')
array([ 0, 20, 4], dtype=uint8)
لتجنب الفائض ، يجب أن تكون المصفوفات قادرة على احتواء قيم تتجاوز 255. تحتاج إلى ذلك تحويلها إلى عوامات على سبيل المثال ، قم بإجراء عملية المزج و تحويل النتيجة مرة أخرى إلى UINT8:
im1arrF = im1arr.astype('float')
im2arrF = im2arr.astype('float')
additionF = (im1arrF+im2arrF)/2
addition = additionF.astype('uint8')
أنت لا يجب افعل هذا:
addition = im1arr/2 + im2arr/2
عندما تفقد المعلومات ، من خلال سحق ديناميكية الصورة (تقوم بفعالية الصور 7 بت) قبل إجراء معلومات المزج.
مذكرة ماتلب: السبب في أنك لا ترى هذه المشكلة في Matlab ، ربما يكون Matlab يعتني بالتدفق الضمني في إحدى وظائفه.
نصائح أخرى
باستخدام مزيج PIL () بقيمة ألفا 0.5 سيكون مكافئًا لـ (IM1ARR + IM2ARR)/2. لا يتطلب مزيج أن تكون الصور لها طبقات ألفا.
جرب هذا:
from PIL import Image
im1 = Image.open('/Users/rem7/Desktop/_1.jpg')
im2 = Image.open('/Users/rem7/Desktop/_2.jpg')
Image.blend(im1,im2,0.5).save('/Users/rem7/Desktop/a.jpg')
يبدو أن الكود الذي نشرته يلخص فقط القيم والقيم أكبر من 256 تفيض. تريد شيئًا مثل "(A + B) / 2" أو "Min (A + B ، 256)". يبدو أن هذا الأخير هو الطريقة التي يفعل بها مثال MATLAB الخاص بك.
إلى قيم صفيف numpy:
>>> c = a + b
>>> c[c > 256] = 256
لا تظهر الصور الخاصة بك نموذجًا ، لذا سأقوم ببعض التخمين.
لا أستطيع أن أتذكر بالضبط كيف يعمل تحويل Numpy إلى PIL ولكن هناك حالتان محتملان. أنا متأكد بنسبة 95 ٪ من أنها 1 لكنني أعطي 2 فقط في حال كنت مخطئًا. 1) 1 im1arr عبارة عن مجموعة MXN من الأعداد الصحيحة (ArgB) وعندما تضيف IM1arr و iM2arr معًا ، فأنت تفيض من قناة واحدة إلى التالي إذا كانت المكونات B1+B2> 255. أظن أن Matlab يمثل صورهم كصفائف MXNX3 بحيث تكون كل قناة ملونة منفصلة. يمكنك حل هذا عن طريق تقسيم قنوات صور PIL ثم صنع صفائف numpy
2) 1 im1arr عبارة عن مجموعة Mxnx3 من البايتات وعندما تضيف IM1arr و iM2arr معًا ، فإنك تلتف المكون حولها.
سيتعين عليك أيضًا إنقاذ النطاق مرة أخرى إلى ما بين 0-255 قبل العرض. اختياراتك تقسم على 2 ، مقياس على 255/array.max () أو القيام بمقطع. لا أعرف ماذا يفعل ماتلاب