OpenCV 显示错误的颜色
OpenCV display the wrong color
我正在使用 C++ 使用 OpenCV。我想创建一个具有 3 种颜色的图像:红色、白色和黑色。详细地说,根据某些条件,我希望背景为红色,然后是白色和黑色。
我遇到的问题是,当我将颜色设置为白色时,它会变成蓝色。
有人能知道为什么会这样以及如何解决吗?
这是我的代码:
//initial image total red
cv::Mat image(Size(w, h), CV_8UC3, cv::Scalar(0, 0, 255));
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
int pixel_v = (int)imggray.at<uchar>(i,j);
if (pixel_v < 200) {
int pixel_bl = (int)imgBool.at<uchar>(i, j);
if (pixel_bl > 200) {
//HERE A WANT WHITE PIXELS, but they are blue
image.at<Vec3b>(i, j) = (255, 255, 255);
}
else {
//black: this works
image.at<Vec3b>(i, j) = (0, 0, 0);
}
}
}
}
OpenCV 使用图像格式 BGR(蓝、绿、红)
当你写这行时:
image.at<Vec3b>(i, j) = (255, 255, 255);
相当于:
image.at<Vec3b>(i, j) = (255);
(参见 this SO answer 解释原因。)
它只将第一个通道设置为最大并且恰好是蓝色。
你需要做的是编辑整个像素,像这样:
// get pixel
Vec3b color = image.at<Vec3b>(Point(x,y));
color[0] = 255;
color[1] = 255;
color[2] = 255;
// set pixel
image.at<Vec3b>(Point(x,y)) = color;
Borrowed from this answer
因此您的代码需要如下所示:
cv::Mat image(Size(w, h), CV_8UC3, cv::Scalar(0, 0, 255));
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
int pixel_v = (int)imggray.at<uchar>(i,j);
if (pixel_v < 200) {
int pixel_bl = (int)imgBool.at<uchar>(i, j);
if (pixel_bl > 200) {
//HERE A WANT WHITE PIXELS, but they are blue
Vec3b color = image.at<Vec3b>(Point(i,j));
color[0] = 255;
color[1] = 255;
color[2] = 255;
image.at<Vec3b>(Point(i,j)) = color;
}
else {
image.at<Vec3b>(i, j) = (0, 0, 0);
}
}
}
}
我在 C++ 中使用 opencv。我从 java 收到一张图片,然后使用此方法将其放入缓冲区:
private fun YUV_420_888_dataToBuffer(image: Image): ByteArray? {
try {
val imageWidth = image.width
val imageHeight = image.height
val planes = image.planes
val data = ByteArray(imageWidth * imageHeight * ImageFormat.getBitsPerPixel(ImageFormat.YUV_420_888) / 8 )
var offset = 0
for (plane in planes.indices) {
val buffer = planes[plane].buffer
val rowStride = planes[plane].rowStride
val pixelStride = planes[plane].pixelStride
val planeWidth = if (plane == 0) imageWidth else imageWidth / 2
val planeHeight = if (plane == 0) imageHeight else imageHeight / 2
if (pixelStride == 1 && rowStride == planeWidth) {
// Copy whole plane from buffer into |data| at once.
buffer[data, offset, planeWidth * planeHeight]
offset += planeWidth * planeHeight
} else {
// Copy pixels one by one respecting pixelStride and rowStride.
val rowData = ByteArray(rowStride)
for (row in 0 until planeHeight - 1) {
buffer[rowData, 0, rowStride]
for (col in 0 until planeWidth) {
data[offset++] = rowData[col * pixelStride]
}
}
buffer[rowData, 0, Math.min(rowStride, buffer.remaining())]
for (col in 0 until planeWidth) {
data[offset++] = rowData[col * pixelStride]
}
}
}
return data
} catch (e: Exception) {
return null
}
}
在 C++ 方面,我从字节数组创建一个 Mat,如下所示:
Mat * myuv = new Mat(width, height, CV_8UC1, (unsigned char *) data);
cvtColor(*myuv, *myuv, COLOR_YUV420sp2RGBA, 4);
这里出了什么问题?
我正在使用 C++ 使用 OpenCV。我想创建一个具有 3 种颜色的图像:红色、白色和黑色。详细地说,根据某些条件,我希望背景为红色,然后是白色和黑色。
我遇到的问题是,当我将颜色设置为白色时,它会变成蓝色。
有人能知道为什么会这样以及如何解决吗?
这是我的代码:
//initial image total red
cv::Mat image(Size(w, h), CV_8UC3, cv::Scalar(0, 0, 255));
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
int pixel_v = (int)imggray.at<uchar>(i,j);
if (pixel_v < 200) {
int pixel_bl = (int)imgBool.at<uchar>(i, j);
if (pixel_bl > 200) {
//HERE A WANT WHITE PIXELS, but they are blue
image.at<Vec3b>(i, j) = (255, 255, 255);
}
else {
//black: this works
image.at<Vec3b>(i, j) = (0, 0, 0);
}
}
}
}
OpenCV 使用图像格式 BGR(蓝、绿、红)
当你写这行时:
image.at<Vec3b>(i, j) = (255, 255, 255);
相当于:
image.at<Vec3b>(i, j) = (255);
(参见 this SO answer 解释原因。)
它只将第一个通道设置为最大并且恰好是蓝色。
你需要做的是编辑整个像素,像这样:
// get pixel
Vec3b color = image.at<Vec3b>(Point(x,y));
color[0] = 255;
color[1] = 255;
color[2] = 255;
// set pixel
image.at<Vec3b>(Point(x,y)) = color;
Borrowed from this answer
因此您的代码需要如下所示:
cv::Mat image(Size(w, h), CV_8UC3, cv::Scalar(0, 0, 255));
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
int pixel_v = (int)imggray.at<uchar>(i,j);
if (pixel_v < 200) {
int pixel_bl = (int)imgBool.at<uchar>(i, j);
if (pixel_bl > 200) {
//HERE A WANT WHITE PIXELS, but they are blue
Vec3b color = image.at<Vec3b>(Point(i,j));
color[0] = 255;
color[1] = 255;
color[2] = 255;
image.at<Vec3b>(Point(i,j)) = color;
}
else {
image.at<Vec3b>(i, j) = (0, 0, 0);
}
}
}
}
我在 C++ 中使用 opencv。我从 java 收到一张图片,然后使用此方法将其放入缓冲区:
private fun YUV_420_888_dataToBuffer(image: Image): ByteArray? {
try {
val imageWidth = image.width
val imageHeight = image.height
val planes = image.planes
val data = ByteArray(imageWidth * imageHeight * ImageFormat.getBitsPerPixel(ImageFormat.YUV_420_888) / 8 )
var offset = 0
for (plane in planes.indices) {
val buffer = planes[plane].buffer
val rowStride = planes[plane].rowStride
val pixelStride = planes[plane].pixelStride
val planeWidth = if (plane == 0) imageWidth else imageWidth / 2
val planeHeight = if (plane == 0) imageHeight else imageHeight / 2
if (pixelStride == 1 && rowStride == planeWidth) {
// Copy whole plane from buffer into |data| at once.
buffer[data, offset, planeWidth * planeHeight]
offset += planeWidth * planeHeight
} else {
// Copy pixels one by one respecting pixelStride and rowStride.
val rowData = ByteArray(rowStride)
for (row in 0 until planeHeight - 1) {
buffer[rowData, 0, rowStride]
for (col in 0 until planeWidth) {
data[offset++] = rowData[col * pixelStride]
}
}
buffer[rowData, 0, Math.min(rowStride, buffer.remaining())]
for (col in 0 until planeWidth) {
data[offset++] = rowData[col * pixelStride]
}
}
}
return data
} catch (e: Exception) {
return null
}
}
在 C++ 方面,我从字节数组创建一个 Mat,如下所示:
Mat * myuv = new Mat(width, height, CV_8UC1, (unsigned char *) data);
cvtColor(*myuv, *myuv, COLOR_YUV420sp2RGBA, 4);
这里出了什么问题?