سؤال

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

باستخدام مشغل الالتزام في ثنائية المليئة مع مرشح غاوسي حصلت على هذه الصورة.حلقة الوصل

الآن أقوم بتشغيل نفس الصورة باستخدام الكود الخاص بي

public static int convolve(BufferedImage a,int x,int y){
 int red=0,green=0,blue=0;
      float[] matrix = { 
 0.1710991401561097f, 0.2196956447338621f, 0.1710991401561097f, 
 0.2196956447338621f, 0.28209479177387814f, 0.2196956447338621f, 
 0.1710991401561097f, 0.2196956447338621f, 0.1710991401561097f, 
 };
      for(int i = x;i<x+3;i++){
          for(int j = y;j<y+3;j++){
              int color = a.getRGB(i,j);
              red += Math.round(((color >> 16) & 0xff)*matrix[(i-x)*3+j-y]);
              green += Math.round(((color >> 8) & 0xff)*matrix[(i-x)*3+j-y]);
              blue += Math.round(((color >> 0) & 0xff)*matrix[(i-x)*3+j-y]);

          }
      }

    return (a.getRGB(x, y)&0xFF000000) | (red << 16) | (green << 8) | (blue);
}

والنتيجة التي حصلت عليها هي هذا.حلقة الوصل

أيضا كيف يمكنني تحسين الكود الذي كتبته. يستغرق مشغل الالتصاف في ثنائية المليء 1 ~ 2 ثانية في حين أن الكود الخاص بي حتى لو لم يكن يخدم الغرض الدقيق كما يفترض ، يستغرق 5 ~ 7 ثوان!

قمت بتدوير صورة المصدر عن طريق الخطأ أثناء التحميل. لذا يرجى تجاهل ذلك.

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

المحلول

بادئ ذي بدء ، أنت دون داع (وبشكل خاطئ) تحويل نتيجتك من التعويم إلى int في كل دورة من الحلقة. لك red, green و blue يجب أن يكون من النوع تعويم ويجب أن يتم إرجاعه إلى عدد صحيح فقط بعد الالتواء (عند تحويله إلى RGB):

  float red=0.0f, green = 0.0f, blue = 0.0f
  for(int i = x;i<x+3;i++){
      for(int j = y;j<y+3;j++){
          int color = a.getRGB(i,j);
          red += ((color >> 16) & 0xff)*matrix[(i-x)*3+j-y];
          green += ((color >> 8) & 0xff)*matrix[(i-x)*3+j-y];
          blue += ((color >> 0) & 0xff)*matrix[(i-x)*3+j-y];

      }
  }

return (a.getRGB(x, y)&0xFF000000) | (((int)red) << 16) | (((int)green) << 8) | ((int)blue);

يحدث نزيف الألوان في النتيجة لأن معاملاتك في matrix مخطئون:

0.1710991401561097f + 0.2196956447338621f + 0.1710991401561097f + 
0.2196956447338621f + 0.28209479177387814f + 0.2196956447338621f +
0.1710991401561097f + 0.2196956447338621f + 0.1710991401561097f =

1.8452741

يجب أن يكون مجموع المعاملات في مصفوفة الالتواء غير الواضحة 1.0. عندما تقوم بتطبيق هذه المصفوفة على صورة ، قد تحصل على ألوان تتجاوز 255. عندما يحدث ذلك ، "تنزف" القنوات في القناة التالية (الأزرق إلى الأخضر ، إلخ). صورة خضراء تمامًا مع هذه المصفوفة ستؤدي إلى:

 green = 255 * 1.8452741 ~= 471 = 0x01D7;
 rgb = 0xFF01D700;

وهو أخضر أقل كثافة مع تلميح من الأحمر.

يمكنك إصلاح ذلك بتقسيم المعاملات 1.8452741, ، لكنك تريد أن تتأكد من ذلك:

 (int)(255.0f * (sum of coefficients)) = 255

إذا لم تكن بحاجة إلى إضافة فحص يحد من حجم القنوات إلى 255 ولا تدعها تلتف حولها. على سبيل المثال:

if (red > 255.0f)
   red = 255.0f;

فيما يتعلق بالكفاءة/التحسين:
قد يتم تفسير الفرق في السرعة من خلال هذا الصب والاتصال بالرياضيات. لست على دراية بما فيه الكفاية مع BufferedImage و Raster لنصائحك حول الطريقة الأكثر فعالية للوصول إلى المخزن المؤقت للصور الأساسية.

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