2016-04-22 10 views
1

私はPhdの仕事の一部である問題があります。バイナリ文字列を分割する方法は?

私はピクセルを表す24 bitsのシーケンスを持っています。最も左側の8 bitsはピクセルのredコンポーネントを与え、8 bitsは​​コンポーネントを与え、最も右側の8 bitsblueコンポーネントを与える。ピクセルの赤、緑、青の成分は、それぞれ0(2進数00000000)〜255(2進数11111111)の値をとることができます。

このピクセルの色が、純粋な赤、緑、白または黒に幾何学的に最も近いかどうかを特定する必要があります。 RGB成分(r1, g1, b1)(r2,g2,b2)を有する2つの色の間の幾何学的距離は、純粋な黒のRGB値が(0, 0, 0)あり、純白が(255, 255, 255)であり、純粋な赤は(255, 0, 0)であり、純粋な青色(0, 0, 255)


ある

d = ((r1-r2)^2 + (g1-g2)^2 + (b1-b2)^2)^1/2 

によって与えられます。

私の仕事は、これらの5つの色のどれがピクセルPの色に最も近いかを特定することです。

例えば画素が000000001111111100000110で表される場合、

  • (バイナリで)赤色成分= 00000000 = 0(ベース10)
  • 緑成分= 11111111(バイナリで)= 255
  • =(バイナリで)00000110 = 6

だから(ベース10)は、PのRGB値が青色成分である(ベース10)(0、255、6)

Euclidean Distance of P from pure black (RGB = (0,0,0)): 
d = ((0 - 0)^2 + (255 - 0)^2 + (6 - 0)2))^1/2 = 65061^1/2 

Euclidean Distance of P from pure white (RGB = (255, 255, 255)): 
d = ((0 - 255)^2 + (255 - 255)^2 + (6 - 255)2))^1/2 = 127026^1/2 

Euclidean Distance of P from pure red (RGB = (255, 0, 0)): 
d = ((0 - 255)^2 + (255 - 0)^2 + (6 - 0)^2))^1/2 = 130086^1/2 

Euclidean Distance of P from pure green (RGB = (0, 255, 0)): 
d = ((0 - 0)^2 + (255 - 255)^2 + (6 - 0)^2))^1/2 = 36^1/2 

Euclidean Distance of P from pure blue (RGB = (0, 0, 255)): 
d = ((0 - 0)^2 + (255 - 0)^2 + (6 - 255)^2))^1/2 = 127026^1/2 

上記から、Pは純粋な緑に最も近いことがわかります。 Pは、2色以上から等距離にある場合は、出力 "あいまい"

サンプル入力する必要があります

5 // The first line contains an integer N(1<=N<=100), which is the number of input pixels to follow. 
101111010110011011100100 
110000010101011111101111 
100110101100111111101101 
010111011010010110000011 
000000001111111111111111 

サンプル出力:あなたは24ビットの番号を持っている場合は、として

White 
White 
White 
Green 
Ambiguous 
+7

そして、あなたは何をしようとしたのですか? –

+0

@Thomas申し訳ありませんが、私はCS(アルゴリズムとデータ構造)について多くの背景を持つ必要はありません。私の例では、数学を使って問題を解決する方法を示していますが、デモを作成するための作業コードが必要です – Anatoly

+0

なぜC#でタグ付けされているのですか?これを解決する簡単なプログラムは、PythonやJuliaのようなスクリプト言語で作成する方が簡単だと思われます。 –

答えて

1

ライブJavaScriptの実装は次のとおりです。

function Color(num, name) { 
 
    this.red = (num>>16) & 0xFF; 
 
    this.green = (num>> 8) & 0xFF; 
 
    this.blue = num  & 0xFF; 
 
    this.name = name; 
 
    this.square_dist = function (rgb) { 
 
     return Math.pow(rgb.red - this.red, 2) 
 
      + Math.pow(rgb.green - this.green, 2) 
 
      + Math.pow(rgb.blue - this.blue, 2); 
 
    }; 
 
} 
 

 
var pures = [ 
 
    new Color(0x000000, 'black'), 
 
    new Color(0xFFFFFF, 'white'), 
 
    new Color(0xFF0000, 'red'), 
 
    new Color(0x00FF00, 'green'), 
 
    new Color(0x0000FF, 'blue'), 
 
]; 
 

 
function findNearestColour(num) { 
 
    var rgb = new Color(num), 
 
     name, square, result, 
 
     smallest_square = 0x40000, 
 
     count = 0; 
 
    for (pure of pures) { 
 
     square = pure.square_dist(rgb); 
 
     if (square <= smallest_square) { 
 
      if (square < smallest_square) { 
 
       result = pure.name; 
 
       smallest_square = square; 
 
       count = 0; 
 
      } 
 
      count++; 
 
     } 
 
    } 
 
    return count == 1 ? result : 'ambiguous'; 
 
} 
 

 

 
// I/O 
 

 
var input = document.querySelector('input'); 
 
var output = document.querySelector('pre'); 
 

 
input.oninput = function() { 
 
    // Get input 
 
    var value = input.value; 
 

 
    // Process 
 
    var result = findNearestColour(parseInt(value.trim(), 2)); 
 
    
 
    // Output result 
 
    output.textContent = result; 
 
} 
 
input.oninput();
<input value="101111010110011011100100" size="30"><br> 
 
<pre></pre>

2

を言いますintの場合、特定のビットグループを取得するには、ビット単位のAND(&)と権利シフト(>>)を使用します。 あなたはこれらのバイナリ文字列からそれを読みたいときは

int pixel = 0xf1f2f3; // RGB (0xf1, 0xf2, 0xf3) 

を持つバイナリで0xff = 1111 1111、以来、あなたは何をする必要があるだろう:

int pixel = int.Parse("01110101011...", 2); //Convert from base 2 to int 

をあなただけ

int red = (pixel & 0xff0000) >> 16; 
int blue = (pixel & 0x00ff00) >> 8; 
int green = (pixel & 0x0000ff); 
にしてください

計算を簡単にするため、System.Drawing.Color構造体を使用して色オブジェクトに保存することができます。

var color = System.Drawing.Color.FromArgb(red, blue, green); 

我々は、(あなたが言及した「純色」のすべてを、青、赤、純粋

public static double EucledianColorDistance(Color c_from, Color c_to) 
{ 
    return Math.Sqrt(Math.Pow(c_from.R - c_to.R, 2) + Math.Pow(c_from.G-c_to.G,2) + Math.Pow(c_from.B-c_to.B,2); 
} 

あなたが、その後に行くとc_from定数を保持し、c_toを繰り返すだろうとしてeucledianの距離を計算したいです緑、白、黒)。次に、これらの色すべての距離を計算し、昇順に並べます。距離が最も小さい色が明らかに最良の選択です(配列の位置0が現在最小の距離です)。次の距離d_1d_0からあまり離れていない場合、色はあいまいです。

希望すると、これが始まります。コードの量は非常に少なく、Pythonにも簡単に変換できます。

#!/usr/bin/env pyhton3 

import math 

class Color: 
    """Represents color """ 
    R = 0 
    G = 0 
    B = 0 

    @staticmethod 
    def ColorFromBinary(bin_string): 
     c = Color() 
     pixel = int(sPixel, 2) 
     c.R = (pixel & 0xff0000) >> 16 
     c.G = (pixel & 0x00ff00) >> 8 
     c.B = (pixel & 0x0000ff) 
     return c 

    @staticmethod 
    def ColorFromRGB(r,g,b): 
     c = Color() 
     c.R = r 
     c.G = g 
     c.B = b 
     return c 

    @staticmethod 
    def euclidean_color_distance(c_from, c_to): 
     return math.sqrt(math.pow(c_from.R-c_to.R,2) + math.pow(c_from.G-c_to.G,2) + math.pow(c_from.B-c_to.B, 2)) 

sPixel = input("Give me the binary pixel string: ") 

color = Color.ColorFromBinary(sPixel) 

print("RGB = (%d, %d, %d)" % (color.R, color.G, color.B)) 

print("Distance to pure white is: %f" % Color.euclidean_color_distance(color, Color.ColorFromRGB(0,0,0))) 
print("Distance to pure red is: %f" % Color.euclidean_color_distance(color, Color.ColorFromRGB(255,0,0))) 

実行例

C:> python color.py 
Give me the binary pixel string: 111111110000000000000000 
RGB = (255, 0, 0) 
Distance to pure white is: 255.000000 
Distance to pure red is: 0.000000 
2

あなたは正しい入力を毎回

using System; 
using System.Linq; 

namespace ConsoleApplication2 
{ 
public struct Color 
{ 
    public int red; 
    public int green; 
    public int blue; 
} 

class Program 
{ 
    public static Color PureRed = new Color {red = 255, green = 0, blue = 0}; 
    public static Color PureGreen = new Color {red = 0, green = 255, blue = 0}; 
    public static Color PureBlue = new Color {red = 0, green = 0, blue = 255}; 
    public static Color PureWhite = new Color {red = 255, green = 255, blue = 255}; 
    public static Color PureBlack = new Color {red = 0, green = 0, blue = 0}; 

    static void Main(string[] args) 
    { 
     Console.WriteLine("Enter no of pixels:"); 
     var input = Console.ReadLine(); 
     var n = int.Parse(input); 

     for (int i = 0; i < n; i++) 
     { 
      var inputPixel = GetInputPixel(); 

      var distanceFromRed = GetEucledianDistance(PureRed, inputPixel); 
      var distanceFromGreen = GetEucledianDistance(PureGreen, inputPixel); 
      var distanceFromBlue = GetEucledianDistance(PureBlue, inputPixel); 
      var distanceFromWhite = GetEucledianDistance(PureWhite, inputPixel); 
      var distanceFromBlack = GetEucledianDistance(PureBlack, inputPixel); 

      var minimumEuclidianDistance = new[] 
              { 
               distanceFromRed, 
               distanceFromGreen, 
               distanceFromBlue, 
               distanceFromWhite, 
               distanceFromBlack 
              }.Min(); 

      if (distanceFromRed == minimumEuclidianDistance) 
       Console.WriteLine("Red"); 
      else if (distanceFromGreen == minimumEuclidianDistance) 
       Console.WriteLine("Green"); 
      else if (distanceFromBlue == minimumEuclidianDistance) 
       Console.WriteLine("Blue"); 
      else if (distanceFromWhite == minimumEuclidianDistance) 
       Console.WriteLine("White"); 
      else if (distanceFromBlack == minimumEuclidianDistance) 
       Console.WriteLine("Black"); 
     } 
     Console.ReadLine(); 
    } 
    private static Color GetInputPixel() 
    { 
     Console.WriteLine("Enter pixel value of 24 bits:"); 
     string pixelValue = Console.ReadLine(); 

     string red = pixelValue.Substring(0, 8); 
     string green = pixelValue.Substring(8, 8); 
     string blue = pixelValue.Substring(16, 8); 

     var inputPixel = new Color() 
         { 
          red = Convert.ToInt32(red, 2), 
          green = Convert.ToInt32(green, 2), 
          blue = Convert.ToInt32(blue, 2) 
         }; 
     return inputPixel; 
    } 
    private static int GetEucledianDistance(Color color1, Color color2) 
    { 
     return 
      (int) Math.Sqrt(Math.Pow(color1.red - color2.red, 2) + 
          Math.Pow(color1.green - color2.green, 2) + 
          Math.Pow(color1.blue - color2.blue, 2)); 
    } 
} 
} 

サンプル出力提供する場合、次のC#コードは動作します:

Enter no of pixels: 
1 
Enter pixel value of 24 bits: 
111111110000000000000000 
Red 

最も近い色を提供するDピクセルは "赤" である。ここ

0

ここではPythonの実装は次のとおりです。

# Complete the function below. 
import math 

def distance(lst): 
    labels = ["White", "Black", "Red", "Green", "Blue"] 
    values = [[255, 255, 255], [0, 0, 0], [255, 0, 0], [0, 255, 0], [0, 0, 255]] 
    min_distance = float("inf") 
    result, r_lst = [], [] 
    for idx, v in enumerate(values): 
     distance = math.sqrt(float(lst[0] - v[0]) * float(lst[0] - v[0]) + 
          float(lst[1] - v[1]) * float(lst[1] - v[1]) + 
          float(lst[2] - v[2]) * float(lst[2] - v[2])) 
     r_lst.append(distance) 

    md = min(r_lst) 
    c, idx = r_lst.count(md), r_lst.index(md) 
    return labels[idx] if c == 1 else "Ambiguous" 

def convert_to_number(s): 
    return int(s, 2) 

def ClosestColor(hexcodes): 
    result = [] 
    for hex in hexcodes: 
     rc = convert_to_number(hex[:8]) 
     gc = convert_to_number(hex[8:16]) 
     bc = convert_to_number(hex[16:]) 
     result.append(distance([rc, gc, bc])) 
    return result