我正在使用C ++使用OpenCV。我想用三种颜色创建图像:红色,白色和黑色。详细地说,根据某些条件,我希望背景为红色,然后为白色,部分为黑色。
我遇到的问题是,当我将颜色设置为白色时,它变成蓝色。
有人可以知道为什么会这样以及如何解决吗?
这是我的代码:
//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);
}
}
}
}
答案 0 :(得分:2)
OpenCV使用图像格式BGR(蓝色,绿色,红色)
编写此行时:
image.at<Vec3b>(i, j) = (255, 255, 255);
等同于:
image.at<Vec3b>(i, j) = (255);
(请参阅this SO answer解释原因。)
仅将第一个通道设置为max,而恰好是蓝色。
您需要做的是编辑整个像素,如下所示:
// 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;
因此您的代码将需要如下所示:
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);
}
}
}
}
答案 1 :(得分:-1)
我在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);
这是怎么回事?