我有一个问题,这是我博士工作的一部分。
我有一个代表像素的24 bits
序列。最左边的8 bits
给出了像素的red
分量,中间8 bits
给出了green
分量,最右边的8 bits
给出了blue
分量。像素的红色,绿色和蓝色分量可以取0到0(二进制00000000)到255(二进制11111111)之间的值。
我需要确定此像素的颜色是否几何上最接近纯红色,绿色,白色或黑色。 RGB成分(r1, g1, b1)
和(r2,g2,b2)
的两种颜色之间的几何距离由
d = ( (r1-r2)^2 + (g1-g2)^2 + (b1-b2)^2 ) ^ 1/2
纯黑色的RGB值为(0, 0, 0)
,纯白色为(255, 255, 255)
,纯红色为(255, 0, 0)
,纯蓝色为(0, 0, 255)
我的任务是确定这五种颜色中哪一种最接近像素P
的颜色。
例如,如果像素由000000001111111100000110
表示,则
00000000
(二进制)= 0(基数为10)11111111
(二进制)= 255(基数为10)00000110
(二进制)= 6(基数为10)因此,P的RGB值为(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与两种或多种颜色等距,则应输出“不明确”
示例输入:
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
示例输出:
White
White
White
Green
Ambiguous
答案 0 :(得分:2)
如果你有24位数字,比如int
,你可以使用按位AND(&
)和右移(>>
)来获取特定群组比特。
由于0xff = 1111 1111
是二进制的,所以当你有
int pixel = 0xf1f2f3; // RGB (0xf1, 0xf2, 0xf3)
如果您想从这些二进制字符串中读取它,您必须执行以下操作:
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);
我们将eucledian距离计算为
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
不变,并通过所有&#34;纯色&#34;迭代c_to
。你提到过(纯红色,蓝色,绿色,白色,黑色)。然后,您可以计算所有这些颜色的距离,并按升序排序。具有最小距离的颜色显然是最佳选择(比如阵列中的位置0现在具有最小距离),但如果下一距离d_1
距离d_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
答案 1 :(得分:2)
如果每次都提供正确的输入,则以下C#代码将起作用
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));
}
}
}
示例输出:
Enter no of pixels:
1
Enter pixel value of 24 bits:
111111110000000000000000
Red
其中提供像素的最近颜色为&#34;红色&#34;
答案 2 :(得分: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();
&#13;
<input value="101111010110011011100100" size="30"><br>
<pre></pre>
&#13;
答案 3 :(得分: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