1. ホーム
  2. スクリプト・コラム
  3. ルビートピックス

画像フィルターアルゴリズムコードのRuby実装

2022-01-03 02:25:37

オリジナル画像


I. グレースケールアルゴリズム

カラー写真の各画素の色値は、赤、緑、青の値が混ざったものです。赤、緑、青の値は多くの種類から取られているので、画素の色値も多くの色値を持つことができ、これがカラー写真の原理ですが、グレースケール写真には256色しかありません。一般的な処理方法は、写真の色値をRGB3チャンネルの値を同じにすることで、グレーで表示されるようになります。

グレースケール処理には、一般的に3つのアルゴリズムがあります。

  1. Max方式:すなわち、新しい色値R = G = B = Max(R, G, B)とする。この方法は、輝度値が高く見えるように画像を処理する。
  2. 平均法。新しい色値R = G = B = (R + G + B) / 3となり、非常にソフトな画像となる
  3. 加重平均法:新しい色の値R = G = B =(R * Wr + G * Wg + B * Wb)、一般的に人間の目は異なる色に同じ感度ではないため、3つの色の値の重みは同じではありませんが、一般的に言えば、緑は赤が続く、最高であり、青は最低です、最も合理的な値はWr = 30%、Wg = 59%、Wb = 11%です。

ここでは、加重平均法のRuby実装を紹介します。

 #Grayscale the image
 #Take the average of the three RGB colors
 def self.grey(bmp)
  for i in 0 ... bmp.height - 1
   for j in 0 ... bmp.width - 1
    rgb = bmp.getRGB(i, j)
    grey = rgb.r.to_f * 0.3 + rgb.g.to_f * 0.59 + rgb.b.to_f * 0.11.to_i
    bmp.setRGB(i, j, RGB.new(grey, grey, grey))
   end
  end
 end

グレースケール効果。


II. 二値化

画像の二値化とは、画像上の画素点のグレー値を0または255にすることで、画像全体がはっきりとした白黒の効果で表現されることを意味します。閾値以上のグレースケールを持つすべてのピクセルは、グレースケール値255で示される特定のオブジェクトに属すると判断され、そうでなければ、これらのピクセル点はオブジェクト領域から除外され、グレースケール値0は、背景または例外的なオブジェクト領域であることを示します。

画像の二値化は、CAPTCHAの解読などの画像認識アプリケーションでよく使用されます。

#Binarize images
 # less than a certain threshold set to 0 0 0, greater than set to 255 255 255
 def self.binarization(bmp)
  imageGreyLevel = bmp.getGreyLevel
  for i in 0 ... bmp.height - 1
   for j in 0 ... bmp.width - 1
    rgb = bmp.getRGB(i, j)
    if rgb.getGreyLevel<imageGreyLevel
     bmp.setRGB(i, j, RGB.new(0, 0, 0))
    else
     bmp.setRGB(i, j, RGB.new(255, 255, 255))
    end
   end

  end
 end

二値化効果


 III. ネガティヴ

ネガティブ効果は、RGBチャンネルの各値を反転、つまり

#negative image
 #RGB takes the inverse color 255-
 def self.contraryColor(bmp)
  for i in 0 ... bmp.height - 1
   for j in 0 ... bmp.width - 1
    rgb = bmp.getRGB(i, j)
    bmp.setRGB(i, j, rgb.getContrary)
   end
  end
 end

マイナス効果


IV. エンボス効果

エンボスのアルゴリズムは比較的複雑で、隣接する点のRGB値から現在の点のRGB値を引き、新しいRGB値として128を足すというものである。画像中の隣接する点の色値は比較的近いので、このようなアルゴリズム処理後は、色のエッジ部分、つまり隣接する色の差が大きい部分だけが目立つ結果となり、その他の滑らかな部分は128程度に近い値、つまり灰色となるため
レリーフのような効果があります。

実際には、この処理をしてもまだドットやバーが残っている部分があるので、新しいRGB値でグレースケール処理をするのがベストです。

#Embossed effect
 The algorithm for #embossing is relatively complex, subtracting the RGB value of the current point from the RGB value of the adjacent points and adding 128 as the new RGB value. Since the color values of the adjacent points in the image are relatively close to each other, the
 # Therefore, after such an algorithm is processed, only the border area of the color, that is, the part of the neighboring color that is more different, will have a more obvious result, while the other smooth areas will have values close to 128 or so.
 #That is, gray, so that it has a relief effect.
 #In practice, some areas may still have "colored" dots or bars after this process, so it's best to do a grayscale process on the new RGB values.
 def self.emboss(bmp)

  preRGB=RGB.new(128, 128, 128)

  for i in 0 ... bmp.height - 1
   for j in 0 ... bmp.width - 1
    currentRGB=bmp.getRGB(i, j)
    r=(currentRGB.r - preRGB.r)*1+128
    g=(currentRGB.g - preRGB.g)*1+128
    b=(currentRGB.b-preRGB.b)*1+128

    bmp.setRGB(i, j, RGB.new(r,g,b).getGreyRGB)
    preRGB = currentRGB
   end
  end

 end

エンボス効果


プロジェクトホームページ

オタク / RubyImageProcess(ルビーイメージプロセス