2009-05-24 4 views
13

का उपयोग कर बिटमैप पर तेज करें मैं एक छवि पर एक तेज फ़िल्टर रखना चाहता हूं। मुझे एक वेब with short tutorial मिला है। मैंने इसे सी # में करने की कोशिश की तो मेरा कोड यहां है। वैसे भी, मैंने यह पता लगाने की कोशिश की कि यह क्यों काम नहीं कर रहा है। मुझे नहीं पता कि मैं कुछ गलत कर रहा हूं, अगर हां, तो कृपया मुझे सलाह दें कि इसे काम करने के लिए क्या करना चाहिए। धन्यवादसी #

 public static Bitmap sharpen(Bitmap image) 
    { 
     Bitmap sharpenImage = new Bitmap(image.Width, image.Height); 

     int filterWidth = 3; 
     int filterHeight = 3; 
     int w = image.Width; 
     int h = image.Height; 

     double[,] filter = new double[filterWidth, filterHeight]; 

     filter[0, 0] = filter[0, 1] = filter[0, 2] = filter[1, 0] = filter[1, 2] = filter[2, 0] = filter[2, 1] = filter[2, 2] = -1; 
     filter[1, 1] = 9; 

     double factor = 1.0; 
     double bias = 0.0; 

     Color[,] result = new Color[image.Width, image.Height]; 

     for (int x = 0; x < w; ++x) 
     { 
      for (int y = 0; y < h; ++y) 
      { 
       double red = 0.0, green = 0.0, blue = 0.0; 
       Color imageColor = image.GetPixel(x, y); 

       for (int filterX = 0; filterX < filterWidth; filterX++) 
       { 
        for (int filterY = 0; filterY < filterHeight; filterY++) 
        { 
         int imageX = (x - filterWidth/2 + filterX + w) % w; 
         int imageY = (y - filterHeight/2 + filterY + h) % h; 
         red += imageColor.R * filter[filterX, filterY]; 
         green += imageColor.G * filter[filterX, filterY]; 
         blue += imageColor.B * filter[filterX, filterY]; 
        } 
        int r = Math.Min(Math.Max((int)(factor * red + bias), 0), 255); 
        int g = Math.Min(Math.Max((int)(factor * green + bias), 0), 255); 
        int b = Math.Min(Math.Max((int)(factor * blue + bias), 0), 255); 

        result[x, y] = Color.FromArgb(r, g, b); 
       } 
      } 
     } 
     for (int i = 0; i < w; ++i) 
     { 
      for (int j = 0; j < h; ++j) 
      { 
       sharpenImage.SetPixel(i, j, result[i, j]); 
      } 
     } 
     return sharpenImage; 
    } 
+0

वहाँ की "सुंदर कोड" दिलचस्प अध्याय लिखा है चार्ल्स पेटज़ोल्ड ने "छवि प्रसंस्करण के लिए ऑन-द-फ्लाई कोड जेनरेशन" नाम दिया। आप इसे बहुत उपयोगी पा सकते हैं। – okutane

उत्तर

25
public static Bitmap sharpen(Bitmap image) 
{ 
    Bitmap sharpenImage = new Bitmap(image.Width, image.Height); 

    int filterWidth = 3; 
    int filterHeight = 3; 
    int w = image.Width; 
    int h = image.Height; 

    double[,] filter = new double[filterWidth, filterHeight]; 

    filter[0, 0] = filter[0, 1] = filter[0, 2] = filter[1, 0] = filter[1, 2] = filter[2, 0] = filter[2, 1] = filter[2, 2] = -1; 
    filter[1, 1] = 9; 

    double factor = 1.0; 
    double bias = 0.0; 

    Color[,] result = new Color[image.Width, image.Height]; 

    for (int x = 0; x < w; ++x) 
    { 
     for (int y = 0; y < h; ++y) 
     { 
      double red = 0.0, green = 0.0, blue = 0.0; 

//=====[REMOVE LINES]======================================================== 
// Color must be read per filter entry, not per image pixel. 
      Color imageColor = image.GetPixel(x, y); 
//=========================================================================== 

      for (int filterX = 0; filterX < filterWidth; filterX++) 
      { 
       for (int filterY = 0; filterY < filterHeight; filterY++) 
       { 
        int imageX = (x - filterWidth/2 + filterX + w) % w; 
        int imageY = (y - filterHeight/2 + filterY + h) % h; 

//=====[INSERT LINES]======================================================== 
// Get the color here - once per fiter entry and image pixel. 
        Color imageColor = image.GetPixel(imageX, imageY); 
//=========================================================================== 

        red += imageColor.R * filter[filterX, filterY]; 
        green += imageColor.G * filter[filterX, filterY]; 
        blue += imageColor.B * filter[filterX, filterY]; 
       } 
       int r = Math.Min(Math.Max((int)(factor * red + bias), 0), 255); 
       int g = Math.Min(Math.Max((int)(factor * green + bias), 0), 255); 
       int b = Math.Min(Math.Max((int)(factor * blue + bias), 0), 255); 

       result[x, y] = Color.FromArgb(r, g, b); 
      } 
     } 
    } 
    for (int i = 0; i < w; ++i) 
    { 
     for (int j = 0; j < h; ++j) 
     { 
      sharpenImage.SetPixel(i, j, result[i, j]); 
     } 
    } 
    return sharpenImage; 
} 
+1

धन्यवाद, आपका उत्तर वास्तव में उपयोगी था – Allek

23

मैं, डैनियल का जवाब लिया और प्रदर्शन के लिए इसे संशोधित, BitmapData वर्ग का उपयोग करके के बाद से GetPixel/SetPixel का उपयोग कर बहुत महंगा और प्रदर्शन के भूखे सिस्टम के लिए अनुचित है। यह पिछले समाधान के समान ही काम करता है और इसके बजाए इसका उपयोग किया जा सकता है।

public static Bitmap Sharpen(Bitmap image) 
    { 
     Bitmap sharpenImage = (Bitmap)image.Clone(); 

     int filterWidth = 3; 
     int filterHeight = 3; 
     int width = image.Width; 
     int height = image.Height; 

     // Create sharpening filter. 
     double[,] filter = new double[filterWidth, filterHeight]; 
     filter[0, 0] = filter[0, 1] = filter[0, 2] = filter[1, 0] = filter[1, 2] = filter[2, 0] = filter[2, 1] = filter[2, 2] = -1; 
     filter[1, 1] = 9; 

     double factor = 1.0; 
     double bias = 0.0; 

     Color[,] result = new Color[image.Width, image.Height]; 

     // Lock image bits for read/write. 
     BitmapData pbits = sharpenImage.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 

     // Declare an array to hold the bytes of the bitmap. 
     int bytes = pbits.Stride * height; 
     byte[] rgbValues = new byte[bytes]; 

     // Copy the RGB values into the array. 
     System.Runtime.InteropServices.Marshal.Copy(pbits.Scan0, rgbValues, 0, bytes); 

     int rgb; 
     // Fill the color array with the new sharpened color values. 
     for (int x = 0; x < width; ++x) 
     { 
      for (int y = 0; y < height; ++y) 
      { 
       double red = 0.0, green = 0.0, blue = 0.0; 

       for (int filterX = 0; filterX < filterWidth; filterX++) 
       { 
        for (int filterY = 0; filterY < filterHeight; filterY++) 
        { 
         int imageX = (x - filterWidth/2 + filterX + width) % width; 
         int imageY = (y - filterHeight/2 + filterY + height) % height; 

         rgb = imageY * pbits.Stride + 3 * imageX; 

         red += rgbValues[rgb + 2] * filter[filterX, filterY]; 
         green += rgbValues[rgb + 1] * filter[filterX, filterY]; 
         blue += rgbValues[rgb + 0] * filter[filterX, filterY]; 
        } 
        int r = Math.Min(Math.Max((int)(factor * red + bias), 0), 255); 
        int g = Math.Min(Math.Max((int)(factor * green + bias), 0), 255); 
        int b = Math.Min(Math.Max((int)(factor * blue + bias), 0), 255); 

        result[x, y] = Color.FromArgb(r, g, b); 
       } 
      } 
     } 

     // Update the image with the sharpened pixels. 
     for (int x = 0; x < width; ++x) 
     { 
      for (int y = 0; y < height; ++y) 
      { 
       rgb = y * pbits.Stride + 3 * x; 

       rgbValues[rgb + 2] = result[x, y].R; 
       rgbValues[rgb + 1] = result[x, y].G; 
       rgbValues[rgb + 0] = result[x, y].B; 
      } 
     } 

     // Copy the RGB values back to the bitmap. 
     System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, pbits.Scan0, bytes); 
     // Release image bits. 
     sharpenImage.UnlockBits(pbits); 

     return sharpenImage; 
    } 
7

यह एक नरम sharpening प्रभाव पैदा करेगा। यदि आपको आवश्यकता हो तो फ़िल्टर सरणी का विस्तार कर सकते हैं, या 16 को कुछ बड़े में बदल सकते हैं, लेकिन मुझे लगता है कि यह आपके जैसा कठोर नहीं है।

const int filterWidth = 5; 
const int filterHeight = 5; 

double[,] filter = new double[filterWidth,filterHeight] { 
    { -1, -1, -1, -1, -1 }, 
    { -1, 2, 2, 2, -1 }, 
    { -1, 2, 16, 2, -1 }, 
    { -1, 2, 2, 2, -1 }, 
    { -1, -1, -1, -1, -1 } 
}; 

double factor = 1.0/16.0; 
3

मैंने निएहर और डेविड के जवाब को संयुक्त किया और "पूर्वाग्रह" संपत्ति तय की। अब आप 0.0 और 1.0 के बीच Sharpen() फ़ंक्शन में "ताकत" पारित कर सकते हैं।

/// <summary> 
///  Sharpens the specified image. 
/// </summary> 
/// <param name="image">The image.</param> 
/// <param name="strength">The strength between 0.0 and 1.0.</param> 
/// <returns></returns> 
public static Bitmap Sharpen(Image image, double strength) 
{ 
    using (var bitmap = image as Bitmap) 
    { 
     if (bitmap != null) 
     { 
      var sharpenImage = bitmap.Clone() as Bitmap; 

      int width = image.Width; 
      int height = image.Height; 

      // Create sharpening filter. 
      const int filterWidth = 5; 
      const int filterHeight = 5; 

      var filter = new double[,] 
       { 
        {-1, -1, -1, -1, -1}, 
        {-1, 2, 2, 2, -1}, 
        {-1, 2, 16, 2, -1}, 
        {-1, 2, 2, 2, -1}, 
        {-1, -1, -1, -1, -1} 
       }; 

      double bias = 1.0 - strength; 
      double factor = strength/16.0; 

      var result = new Color[image.Width,image.Height]; 

      // Lock image bits for read/write. 
      if (sharpenImage != null) 
      { 
       BitmapData pbits = sharpenImage.LockBits(new Rectangle(0, 0, width, height), 
                  ImageLockMode.ReadWrite, 
                  PixelFormat.Format24bppRgb); 

       // Declare an array to hold the bytes of the bitmap. 
       int bytes = pbits.Stride*height; 
       var rgbValues = new byte[bytes]; 

       // Copy the RGB values into the array. 
       Marshal.Copy(pbits.Scan0, rgbValues, 0, bytes); 

       int rgb; 
       // Fill the color array with the new sharpened color values. 
       for (int x = 0; x < width; ++x) 
       { 
        for (int y = 0; y < height; ++y) 
        { 
         double red = 0.0, green = 0.0, blue = 0.0; 

         for (int filterX = 0; filterX < filterWidth; filterX++) 
         { 
          for (int filterY = 0; filterY < filterHeight; filterY++) 
          { 
           int imageX = (x - filterWidth/2 + filterX + width)%width; 
           int imageY = (y - filterHeight/2 + filterY + height)%height; 

           rgb = imageY*pbits.Stride + 3*imageX; 

           red += rgbValues[rgb + 2]*filter[filterX, filterY]; 
           green += rgbValues[rgb + 1]*filter[filterX, filterY]; 
           blue += rgbValues[rgb + 0]*filter[filterX, filterY]; 
          } 

          rgb = y*pbits.Stride + 3*x; 

          int r = Math.Min(Math.Max((int) (factor*red + (bias*rgbValues[rgb + 2])), 0), 255); 
          int g = Math.Min(Math.Max((int) (factor*green + (bias*rgbValues[rgb + 1])), 0), 255); 
          int b = Math.Min(Math.Max((int) (factor*blue + (bias*rgbValues[rgb + 0])), 0), 255); 

          result[x, y] = Color.FromArgb(r, g, b); 
         } 
        } 
       } 

       // Update the image with the sharpened pixels. 
       for (int x = 0; x < width; ++x) 
       { 
        for (int y = 0; y < height; ++y) 
        { 
         rgb = y*pbits.Stride + 3*x; 

         rgbValues[rgb + 2] = result[x, y].R; 
         rgbValues[rgb + 1] = result[x, y].G; 
         rgbValues[rgb + 0] = result[x, y].B; 
        } 
       } 

       // Copy the RGB values back to the bitmap. 
       Marshal.Copy(rgbValues, 0, pbits.Scan0, bytes); 
       // Release image bits. 
       sharpenImage.UnlockBits(pbits); 
      } 

      return sharpenImage; 
     } 
    } 
    return null; 
} 
3

ठीक है, विकृत किनारों के साथ समस्या को ठीक किया गया है। Here's अद्यतन एक:

/// <summary> 
/// Sharpens the specified image. 
/// </summary> 
/// <param name="image">The image.</param> 
/// <param name="strength">The strength.</param> 
/// <returns></returns> 
public static Bitmap Sharpen(Image image, double strength) 
{ 
    using (var bitmap = image as Bitmap) 
    { 
     if (bitmap != null) 
     { 
      var sharpenImage = bitmap.Clone() as Bitmap; 

      int width = image.Width; 
      int height = image.Height; 

      // Create sharpening filter. 
      const int filterSize = 5; 

      var filter = new double[,] 
       { 
        {-1, -1, -1, -1, -1}, 
        {-1, 2, 2, 2, -1}, 
        {-1, 2, 16, 2, -1}, 
        {-1, 2, 2, 2, -1}, 
        {-1, -1, -1, -1, -1} 
       }; 

      double bias = 1.0 - strength; 
      double factor = strength/16.0; 

      const int s = filterSize/2; 

      var result = new Color[image.Width,image.Height]; 

      // Lock image bits for read/write. 
      if (sharpenImage != null) 
      { 
       BitmapData pbits = sharpenImage.LockBits(new Rectangle(0, 0, width, height), 
                  ImageLockMode.ReadWrite, 
                  PixelFormat.Format24bppRgb); 

       // Declare an array to hold the bytes of the bitmap. 
       int bytes = pbits.Stride*height; 
       var rgbValues = new byte[bytes]; 

       // Copy the RGB values into the array. 
       Marshal.Copy(pbits.Scan0, rgbValues, 0, bytes); 

       int rgb; 
       // Fill the color array with the new sharpened color values. 
       for (int x = s; x < width - s; x++) 
       { 
        for (int y = s; y < height - s; y++) 
        { 
         double red = 0.0, green = 0.0, blue = 0.0; 

         for (int filterX = 0; filterX < filterSize; filterX++) 
         { 
          for (int filterY = 0; filterY < filterSize; filterY++) 
          { 
           int imageX = (x - s + filterX + width)%width; 
           int imageY = (y - s + filterY + height)%height; 

           rgb = imageY*pbits.Stride + 3*imageX; 

           red += rgbValues[rgb + 2]*filter[filterX, filterY]; 
           green += rgbValues[rgb + 1]*filter[filterX, filterY]; 
           blue += rgbValues[rgb + 0]*filter[filterX, filterY]; 
          } 

          rgb = y * pbits.Stride + 3 * x; 

          int r = Math.Min(Math.Max((int)(factor * red + (bias * rgbValues[rgb + 2])), 0), 255); 
          int g = Math.Min(Math.Max((int)(factor * green + (bias * rgbValues[rgb + 1])), 0), 255); 
          int b = Math.Min(Math.Max((int)(factor * blue + (bias * rgbValues[rgb + 0])), 0), 255); 

          result[x, y] = Color.FromArgb(r, g, b); 
         } 
        } 
       } 

       // Update the image with the sharpened pixels. 
       for (int x = s; x < width - s; x++) 
       { 
        for (int y = s; y < height - s; y++) 
        { 
         rgb = y*pbits.Stride + 3*x; 

         rgbValues[rgb + 2] = result[x, y].R; 
         rgbValues[rgb + 1] = result[x, y].G; 
         rgbValues[rgb + 0] = result[x, y].B; 
        } 
       } 

       // Copy the RGB values back to the bitmap. 
       Marshal.Copy(rgbValues, 0, pbits.Scan0, bytes); 
       // Release image bits. 
       sharpenImage.UnlockBits(pbits); 
      } 

      return sharpenImage; 
     } 
    } 
    return null; 
} 
1

हाय मैं कोड से थोड़ा अधिक बिट को संपादित करने और दो अन्य मैट्रिक्स जोड़ने मेरे लिए यह काम करता है अब सही

/// <summary> 
    /// Sharpens the specified image. 
    /// </summary> 
    /// <param name="image">The image.</param> 
    /// <param name="strength">strength erwartet werte zwische 0 - 99</param> 
    /// <returns></returns> 
    public Bitmap Sharpen(Image image, whichMatrix welcheMatrix , double strength) 
    { 
     double FaktorKorrekturWert = 0; 

     //strenght muß für den jeweiligen filter angepasst werden 
     switch (welcheMatrix) 
     { 
      case whichMatrix.Gaussian3x3: 
       //diese Matrix benötigt einen strenght Wert von 0 bis -9.9 default ist -2.5 
       //und einen korekturwert von 16 
       strength = (strength * -1)/10; 
       FaktorKorrekturWert = 16; 
       break; 

      case whichMatrix.Mean3x3: 
       //diese Matrix benötigt einen strenght Wert von 0 bis -9 default ist -2.25 
       //und einen Korrekturwert von 10 
       strength = strength * -9/100; 
       FaktorKorrekturWert = 10; 
       break; 

      case whichMatrix.Gaussian5x5Type1: 
       //diese Matrix benötigt einen strenght Wert von 0 bis 2.5 default ist 1.25 
       //und einen Korrekturwert von 12 
       strength = strength * 2.5/100; 
       FaktorKorrekturWert = 12; 
       break; 

      default: 
       break; 
     } 

     using (var bitmap = image as Bitmap) 
     { 
      if (bitmap != null) 
      { 
       var sharpenImage = bitmap.Clone() as Bitmap; 

       int width = image.Width; 
       int height = image.Height; 

       // Create sharpening filter. 
       var filter = Matrix(welcheMatrix); 

       //const int filterSize = 3; // wenn die Matrix 3 Zeilen und 3 Spalten besitzt dann 3 bei 4 = 4 usw.      
       int filterSize = filter.GetLength(0);     

       double bias = 1.0 - strength; 
       double factor = strength/FaktorKorrekturWert; 

       //const int s = filterSize/2; 
       int s = filterSize/2; // Filtersize ist keine Constante mehr darum wurde der befehl const entfernt 


       var result = new Color[image.Width, image.Height]; 

       // Lock image bits for read/write. 
       if (sharpenImage != null) 
       { 
        BitmapData pbits = sharpenImage.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 

        // Declare an array to hold the bytes of the bitmap. 
        int bytes = pbits.Stride * height; 
        var rgbValues = new byte[bytes]; 

        // Copy the RGB values into the array. 
        Marshal.Copy(pbits.Scan0, rgbValues, 0, bytes); 

        int rgb; 
        // Fill the color array with the new sharpened color values. 
        for (int x = s; x < width - s; x++) 
        { 
         for (int y = s; y < height - s; y++) 
         { 
          double red = 0.0, green = 0.0, blue = 0.0; 

          for (int filterX = 0; filterX < filterSize; filterX++) 
          { 
           for (int filterY = 0; filterY < filterSize; filterY++) 
           { 
            int imageX = (x - s + filterX + width) % width; 
            int imageY = (y - s + filterY + height) % height; 

            rgb = imageY * pbits.Stride + 3 * imageX; 

            red += rgbValues[rgb + 2] * filter[filterX, filterY]; 
            green += rgbValues[rgb + 1] * filter[filterX, filterY]; 
            blue += rgbValues[rgb + 0] * filter[filterX, filterY]; 
           } 

           rgb = y * pbits.Stride + 3 * x; 

           int r = Math.Min(Math.Max((int)(factor * red + (bias * rgbValues[rgb + 2])), 0), 255); 
           int g = Math.Min(Math.Max((int)(factor * green + (bias * rgbValues[rgb + 1])), 0), 255); 
           int b = Math.Min(Math.Max((int)(factor * blue + (bias * rgbValues[rgb + 0])), 0), 255); 

           result[x, y] = System.Drawing.Color.FromArgb(r, g, b); 
          } 
         } 
        } 

        // Update the image with the sharpened pixels. 
        for (int x = s; x < width - s; x++) 
        { 
         for (int y = s; y < height - s; y++) 
         { 
          rgb = y * pbits.Stride + 3 * x; 

          rgbValues[rgb + 2] = result[x, y].R; 
          rgbValues[rgb + 1] = result[x, y].G; 
          rgbValues[rgb + 0] = result[x, y].B; 
         } 
        } 

        // Copy the RGB values back to the bitmap. 
        Marshal.Copy(rgbValues, 0, pbits.Scan0, bytes); 
        // Release image bits. 
        sharpenImage.UnlockBits(pbits); 
       } 

       return sharpenImage; 
      } 
     } 
     return null; 
    } 


    public enum whichMatrix 
    { 
     Gaussian3x3, 
     Mean3x3, 
     Gaussian5x5Type1 
    } 


    private double[,] Matrix(whichMatrix welcheMatrix) 
    { 
     double[,] selectedMatrix = null; 

     switch (welcheMatrix) 
     { 
      case whichMatrix.Gaussian3x3: 
       selectedMatrix = new double[,] 
       { 
        { 1, 2, 1, }, 
        { 2, 4, 2, }, 
        { 1, 2, 1, }, 
       }; 
       break; 

      case whichMatrix.Gaussian5x5Type1: 
       selectedMatrix = new double[,] 
       { 
        {-1, -1, -1, -1, -1}, 
        {-1, 2, 2, 2, -1}, 
        {-1, 2, 16, 2, -1}, 
        {-1, 2, -1, 2, -1}, 
        {-1, -1, -1, -1, -1} 
       }; 
       break; 

      case whichMatrix.Mean3x3: 
       selectedMatrix =new double[,] 
       { 
        { 1, 1, 1, }, 
        { 1, 1, 1, }, 
        { 1, 1, 1, }, 
       }; 
       break; 
     } 

     return selectedMatrix; 
    } 
+0

aaalter deutsch und englisch gleichezitig में कोडन संपादित करें? schlechte idee ^^ –