سؤال عن دالة dct ودالة idct

السلام عليكم ورحمة الله وبركاته
الى أسرة العمل في منتدى المهندس أتقدم اليكم بجزيل الشكر والامتنان على ماتقدموامن برامج مفيدة ومعلومات قيمة و أود منكم الاجابة على سؤالي :
أنا الان اقوم بعمل مشروع العلامة المائية باستخدام DCT وقمت بتنفيذ مشروعي باستخدام الماتلاب ولكني لم استطيع فهم استخدام دالة DCT وأريد ايضاً أن أعرف كيف اقسم المعاملات بعد استخدام ال DCT إلى Blocks وحجم كل blocks هو 8*8 ولكم جزيل الشكر وارجوا الاسراع في الاجابة لانه قد تقترب موعد التسليم
والسلام عليكم ورحمة الله وبركاته

بحثي هو digetal watermark بمعنى العلامة المائية الرقمية ولها نوعان الأول مخفي والثاني مرئي وفي بحثي سأستخدم النوع المخفي ولها أيضاً عدة أنواع هي علامة مائية في الصوت أو الصورة أو الفيديو أو النصوص ومشروعي هو تضمين علامة مائية صورة داخل صورة وفكرة البرمجة هي:

أخذ صورتين الأولى هي الصورة الأصلية وتحجيمها إلى 512512 وتحويلها إلى معاملات باستخدام دالة DCT بحيث يسهل استخدام الصورةثم تقسيم هذه المعاملات إلى blocks وحجم كل block هو 88.

والصورة الثانية هي صورة العلامة المائية التي سأخفيها داخل الصورة الأصلية وفي هذه الصورة سيتم تحجيمها إلى 64*64 وتحويلها إلى binary

والخطوة الثانية هي تحديد أضعف معامل من كل block في الصورة الأصلية واستبداله بـ bit من صورة العلامة المائية وهكذا…

وهذه بعض الأكواد التي قد كتبتها:

%read the orgenal image and resize to 512*512
ia=imread('liftingbody.png');
ib=imresize(ia,[512 512]);
figure,imshow(ia);
figure,imshow(ib);
ic=dct2(ib);
%read the watermark image and resize to 64*64
id=imread('liftingbody.png');
ie=imresize(ia,[64 64]);
ig=im2bw(ie);
figure,imshow(ie);
figure,imshow(ig);

أولا دالة dct2 تستخدم لعمل The discrete cosine transform
ممكن تعرفى معلومات عنها من خلال الهيلب او زيارة الصفحة الاتية
https://de.mathworks.com/help/images/ref/dct2.html

وهذه الدالة تطبق على مصفوفة 2D اى ان الصورة تكون gray scale
وبالنسبة للصورة الملونة ممكن تفصلى كل بعد لوحده وبعدين تطبقى الدالة وبعدين تجمعيهم تانى .

ولكن أرى انك استخدمتى صورة gray ولذلك فلا يوجد اى مشكلة من استخدام الدالة مباشرة
وبعد التحويل نجد الان ان المصفوفة الجديد تحتوى على اعداد عشرية وسالبة ولذلك فهى من النوع double ولذلك سيتلزم تحويلها مرة أخرى للنوع uint8 لا الصور لا تصلح ان تكون double .
ولذلك فكرى فى استخدام مثلا abs لجعلها قيم موجبة او مثلا حذف القيم السالبة كما فى المثال الموجود فى الهيلب

J(abs(J) < 10) = 0;

وبالنسبة لعملية التقسيم لبلوكات فلا اعلم اذا كان هناك دالة جاهزة لهذا الموضوع أم لا وان لم يكن فيمكن عملها باستخدام for loop
على سبيل المثال

for i = 0:8:504
    for j = 0:8:504
        [C,I1] = min(min(ic(i+1:i+8,j+1:j+8)));
        [C,I2] = min(min(ic(i+1:i+8,j+1:j+8)'));
        I1 = I1 + j;
        I2 = I2 + i;
        ic(I2,I1)= ig((i/8)+1,(j/8)+1);
    end
end

والان أصبحت ic تحتوى على الصورتين ويمكنك الان تحويلها مرة أخرى باستخدام idct2 وعرض الصورة
ويصبح البرنامج فى شكله النهائى كما يلى

% Read the orgenal image and resize to 512*512
clear
ia = imread('liftingbody.png');
ib = imresize(ia,[512 512]);
imshow (ib)
ic = dct2(ib); % The discrete cosine transform

% Read the watermark image and resize to 64*64
id = imread('liftingbody.png');
ie = imresize(ia,[64 64]);
ig = im2bw(ie);

% Dividing into 8x8 blocks and embed the watermark
for i = 0:8:504
    for j = 0:8:504
        [C,I1] = min( min( ic( i+1:i+8,j+1:j+8 ) ) ); % find the minimum value
        [C,I2] = min( min( ic( i+1:i+8,j+1:j+8 )') );
        I1 = I1 + j; 
        I2 = I2 + i;
        ic(I2,I1)= ig((i/8)+1,(j/8)+1); 
    end
end
newImage = idct2(ic); % The discrete cosine inverse transform
figure, imshow(newImage,[0 255]) % Scaling the new image

جزاك الله خيراً يابشمهندس على هذا المجهود الرائع بس أنا لما حطيت الموضوع كان في خطأ في شرحي هو:
لما أضيف صورة العلامة المائية مش ححط الbit مكان المعامل لانه في معادله كالتالي:

 V′ij = Vij +α Wp(i, j)

V’ij: يعني المعامل الجديد
Vij: المعامل القديم
α: رقم ثابت ولنفرض أنه 0.5
Wp(i,j) :ال bit الذي من العلامة المائية
وعند تطبيق المعادلة السابقة لايحدث أي فرق في الصورة عند اضافة صورة العلامة المائية إلى الصورة الأصلية

ياريت تبعتيلى البرنامج الكامل بعد ما طبقتى ما ذكرتيه وايضا كمان الصورة قبل وبعد
وانا ايضا حاولت تطبيق ما ذكرتيه وكانت النتيجة فعلا انه مفيش فرق كبير بين الصورة الاصلية والصورة بعد وضع العلامة وبسبب انه على سبيل المثال فى البلوك الاول سنجد ان أصغر قيمة تساوى -3.6096e+003
بعد تطبيق المعادلة التى ذكرتيها سيكون المعامل الجديد -3.6091e+003
فعلا سيكون الفرق لا يذكر لانه فى حالة ig تساوى 1 فانه سيتم اضافة 0.5 الى المعامل القديم وفى حالة ig تساوى صفر فانه لن يحدث اى تغيير .
وهذه الطريقة مفيدة فعلا لانه يمكنك فصل العلامة المائية والصورة مرة أخرى ولكن على سبيل المثال يمكنك استخدام العلامة المائية بدون تحويلها الى binary وستشاهدى الفرق الواضح بين الصورتين

هذا البرنامج بعد تطبيق المعادلة التى ذكرتيها

% Read the orgenal image and resize to 512*512
clear
ia = imread('liftingbody.png');
ib = imresize(ia,[512 512]);
imshow (ib)
ic = dct2(ib); % The discrete cosine transform

% Read the watermark image and resize to 64*64
id = imread('liftingbody.png');
ie = imresize(ia,[64 64]);
ig = im2bw(ie);

% Dividing into 8x8 blocks and embed the watermark
for i = 0:8:504
    for j = 0:8:504
        [C,I1] = min( min( ic( i+1:i+8,j+1:j+8 ) ) ); % find the minimum value
        [C,I2] = min( min( ic( i+1:i+8,j+1:j+8 )') );
        I1 = I1 + j; 
        I2 = I2 + i;
        ic(I2,I1)= C + 0.5 * ig((i/8)+1,(j/8)+1); 
    end
end
newImage = idct2(ic); % The discrete cosine inverse transform
figure, imshow(newImage,[0 255]) % Scaling the new image

السلام عليكم ورحمة الله وبركاته ,
الموضوع شدني لانه نفس مشروع انا شغالة عليه …واتمنى تفيدوني كمان
عندي سؤال ؟؟اذا حبيت انه التضمين يكون في mid مش في min اعمل ايه
وكيف اقدر اعمل extract بعد كذا

وعليكم السلام
يرجى التوضيح اكثر عن المقصود حول التضمين فى mid وليس min

مش احنا عشان استخدمنا DCT تم تقسيم الصورة الى ثلاث مستويات high, middle and low frequency الكود اللي حضرتك كاتبه عمل التضمين في المستوى ال low (او هذا على الاقل اللي انا فهمته والمعروف عن هذا المستوى انه بيكون مرئي للعين )بس انا حابة اعمل تضمين في المستوى ال middle … واعتذر اذا كنت ماعرفت اوصل الفكرة لانه انا نفسي لسى مشوشة في هذا الموضوع بس المطلوب مني اني اعمل اخفاء في المستوى الmiddle

بصراحة أول مرة أسمع عن هذا الموضوع ان الصورة 3 مستويات وان المستوى low هو المرئى للعين وفى الحقيقة هذا الموضوع قديم اى من خمس سنين تقريبا ومنذ ذلك الحين لم أعمل فى مجال معالجة الصور
ولكن كما واضح انه يتم حساب القيمة الاقل داخل كل بلوك بعد التقسيم ويمكنك استبدال هذا مثلا بحساب متوسط القيم

ممكن اعرف العلامة المائية المستخدمة هنا هيا visible watermark ولا invisible robust watermark ولا invisible fragile watermark ولا Dual watermark

للاسف الموضوع قديم ولا اتذكر التفاصيل الان