سؤال

لديّ عازلة مع العديد من قيم 16 بت إيجابية (يتم تخزينها كضاعفة) وأود أن أعددها إلى 8bit (0-255 قيم).

بالنسبة الى ويكيبيديا ستكون العملية:

  • قم بتطبيع قيم 16 بت. أي العثور على أكبر وتقسيم مع هذا.
  • استخدم صيغة Q (x) مع M = 8.

لذلك أتساءل ، إذا كانت C لديها وظيفة يمكنها القيام بهذا القياس ، أم أن أي شخص يعرف تنفيذ C يمكنني استخدامه؟

الكثير من الحب ، لويز

هل كانت مفيدة؟

المحلول

على افتراض القيمة d في الفاصل الزمني [0.0, max]:

unsigned char quantize(double d, double max)
{
    return (unsigned char)((d / max) * 255.0);
}

لست متأكدًا مما تقصده بـ "القيم 16 بت" ؛ تكون قيم الدقة المزدوجة 64 بت على أي نظام باستخدام IEEE-754. ومع ذلك ، إذا كان لديك قيم من نوع رقمي آخر ، فإن العملية هي نفسها بشكل فعال.

نصائح أخرى

هذا يبدو مثل معالجة الصوت الموجي ، حيث يكون الإدخال الخاص بك هو 16 بيانات PCM ، والإخراج الخاص بك هو بيانات 8 بت PCM وأنت تستخدم الزوجي كقيمة وسيطة.

ومع ذلك ، فإن بيانات موجة PCM 8 بت ليست فقط كمية ، فإن التمثيل هو قيم غير موقعة تدوين 128. (مثل الطريقة التي يتم بها تخزين الأسس في أرقام النقاط العائمة)

إن العثور على أكبر قيمة أولاً لن يتم تحديد كمياتها فحسب ، بل أيضًا. لذلك في رمز الزائفة

double dMax = max_of_all_values(); // 
...
foreach (dValue in array_of_doubles)
{
   signed char bValue = (signed char)((dValue / dMax)*127.0);
}

يمكنك أن تتجول بدلاً من اقتطاعها إذا كنت تريد المزيد من الدقة ، ولكن في معالجة الصوت ، من الأفضل عمومًا وضع عشوائي لترتيب الاقتطاع أو حتى تشكيله عن طريق تشغيل خوارزمية تصفية بشكل أساسي كجزء من الاقتطاع من الزوجي إلى chars الموقعة.

ملاحظة: لا يكون هذا char الموقّع صحيحًا إذا كان الإخراج عبارة عن بيانات 8 بت PCM ، ولكن نظرًا لأن الأسئلة لا تطلب ذلك على وجه التحديد ، فقد تركتها.

تحرير: إذا تم استخدام هذا كبيانات بكسل ، فأنت تريد قيمًا غير موقعة. أرى أن جيمس أعطى بالفعل الإجابة الصحيحة للقيم غير الموقعة عندما تكون الإدخال غير موقعة (يجب أن تكون قيم DB من البيانات الطبيعية سلبية ، في الواقع)

ليس من الواضح من سؤالك ما هو الترميز منذ ذلك الحين "قيم 16 بت إيجابية (يتم تخزينها كضاعفة)"لا معنى له ، فهي إما 16 بت أو أنها ضعف ، لا يمكن أن تكون كلاهما.

ومع ذلك على افتراض أن هذه البيانات غير موقعة 16 بت تم تطبيعها إلى 1.0 (وبالتالي تتراوح القيم من 0.0 <= س <= 1.0) ، كل ما عليك القيام به لتوسيعها إلى قيم عدد صحيح 8bit هو ضرب كل عينة بمقدار 255.

unsigned char s8 = s * 255 ;

إذا لم يكن النطاق 0.0 <= س <= 1.0 ، لكن 0.0 <= s <= الأعلى من ثم:

unsigned char s8 = s / max * 255 ;

في كلتا الحالتين ، لا توجد وظيفة "كمية" بخلاف وظيفة قد تكتبها بنفسك ؛ لكن التحول اللازم سيكون بلا شك تعبيرًا حسابيًا بسيطًا (على الرغم من أنه ليس بسيطًا إذا تم تجميع البيانات ربما-أي μ-lay أو A-law مشفر على سبيل المثال).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top