我的通道分离计算是否正确?
Are my channel separation calculations correct?
我有一张 HSV 图像,我对图像的某个区域感兴趣。我已经开始选择图像并确定我感兴趣的区域,但我认为我分隔频道的方式不正确。我的通道值不接近它们的实际值。我正在查看的图像部分在 RGB 比例下是白色的。我知道在 HSV 中,白色的饱和度约为 (0..20) 和一个值 (230..255),但程序打印出的数字并不接近该范围。我得到的 S 高 40 低 50,V 主要是 -93。我的通道计算正确吗?
public void splitChannels() {
Mat firstImage = Imgcodecs.imread("firstImage.jpg");
int width = 20;
int height = 20;
Rect roi = new Rect(120, 160, width, height);
Mat smallImg = new Mat(firstImage, roi);
int channels = smallImg.channels();
System.out.println("small pixels:" + smallImg.total());
System.out.println("channels:" + smallImg.channels());
int totalBytes = (int)(smallImg.total() * smallImg.channels());
byte buff[] = new byte[totalBytes];
smallImg.get(0, 0, buff);
for (int i=0; i< height; i++) {
// stride is the number of bytes in a row of smallImg
int stride = channels * width;
for (int j=0; j<stride; j+=channels) {
//I don't know if these channels calculations are correct.
int h = buff[(i * stride) + j];
int s = buff[(i * stride) + j + 1];
int v = buff[(i * stride) + j + 2];
// Do something with the hsv.
System.out.println("s: "+ s + " v: " + v);
}
}
}
这是我的图片:
感兴趣的区域是中间的左上角贴纸,虽然它们都是白色的。
程序为此打印出的 HSV 是:
h: 99 s: 78 v: 57
h: 97 s: 76 v: 55
h: 101 s: 77 v: 57
h: 101 s: 77 v: 57
h: 103 s: 79 v: 59
h: 103 s: 79 v: 59
h: 103 s: 79 v: 59
h: 102 s: 78 v: 58
h: 100 s: 76 v: 58
h: 99 s: 75 v: 57
h: 98 s: 74 v: 56
h: 98 s: 74 v: 56
h: 98 s: 74 v: 54
h: 99 s: 75 v: 55
您似乎得到了正确的值,但它们是来自原始字节的 RGB 强度。它们出现 -1 -1 -1 因为 Java 字节数据类型是 8 位长,但是它是有符号数据类型,而不是无符号数据类型。
您需要将这些值从 RGB 转换为 HSV。试试这个:
这里是 link 到转换的定义:
将默认 RGB 模型指定的颜色分量转换为一组等效的色调、饱和度和亮度值,它们是 HSB 模型的三个分量。
public static float[] RGBtoHSB(int r,
int g,
int b,
float[] hsbvals)
用法:
int r = ...
int g = ...
int b = ...
float[] hsbvals = new float[3];
Color.RGBtoHSB(r,g,b,hsbvals)
我有一张 HSV 图像,我对图像的某个区域感兴趣。我已经开始选择图像并确定我感兴趣的区域,但我认为我分隔频道的方式不正确。我的通道值不接近它们的实际值。我正在查看的图像部分在 RGB 比例下是白色的。我知道在 HSV 中,白色的饱和度约为 (0..20) 和一个值 (230..255),但程序打印出的数字并不接近该范围。我得到的 S 高 40 低 50,V 主要是 -93。我的通道计算正确吗?
public void splitChannels() {
Mat firstImage = Imgcodecs.imread("firstImage.jpg");
int width = 20;
int height = 20;
Rect roi = new Rect(120, 160, width, height);
Mat smallImg = new Mat(firstImage, roi);
int channels = smallImg.channels();
System.out.println("small pixels:" + smallImg.total());
System.out.println("channels:" + smallImg.channels());
int totalBytes = (int)(smallImg.total() * smallImg.channels());
byte buff[] = new byte[totalBytes];
smallImg.get(0, 0, buff);
for (int i=0; i< height; i++) {
// stride is the number of bytes in a row of smallImg
int stride = channels * width;
for (int j=0; j<stride; j+=channels) {
//I don't know if these channels calculations are correct.
int h = buff[(i * stride) + j];
int s = buff[(i * stride) + j + 1];
int v = buff[(i * stride) + j + 2];
// Do something with the hsv.
System.out.println("s: "+ s + " v: " + v);
}
}
}
这是我的图片:
感兴趣的区域是中间的左上角贴纸,虽然它们都是白色的。
程序为此打印出的 HSV 是:
h: 99 s: 78 v: 57
h: 97 s: 76 v: 55
h: 101 s: 77 v: 57
h: 101 s: 77 v: 57
h: 103 s: 79 v: 59
h: 103 s: 79 v: 59
h: 103 s: 79 v: 59
h: 102 s: 78 v: 58
h: 100 s: 76 v: 58
h: 99 s: 75 v: 57
h: 98 s: 74 v: 56
h: 98 s: 74 v: 56
h: 98 s: 74 v: 54
h: 99 s: 75 v: 55
您似乎得到了正确的值,但它们是来自原始字节的 RGB 强度。它们出现 -1 -1 -1 因为 Java 字节数据类型是 8 位长,但是它是有符号数据类型,而不是无符号数据类型。
您需要将这些值从 RGB 转换为 HSV。试试这个: 这里是 link 到转换的定义:
将默认 RGB 模型指定的颜色分量转换为一组等效的色调、饱和度和亮度值,它们是 HSB 模型的三个分量。
public static float[] RGBtoHSB(int r,
int g,
int b,
float[] hsbvals)
用法:
int r = ...
int g = ...
int b = ...
float[] hsbvals = new float[3];
Color.RGBtoHSB(r,g,b,hsbvals)