我正在尝试从 QPixmap 中提取位掩码并将其传递给 OpenCV。我的位掩码是通过“绘画”操作创建的。
到目前为止我的流程是:
创建一个
QPixmap,
QPixmap::fill(QColor(0,0,0,0))
并使用QPainter
使用QPainter::setPen(QColor(255,0,0,255))
到QPainter::drawPoint(mouse_event->pos()
当准备好提取位掩码
QPixmap::toImage()
时,然后是QImage::createAlphaMask()
,它被记录为返回QImage: :Format_MonoLSB
不过我现在正式卡住了。我在解读文档时遇到问题:
Each pixel stored in a QImage is represented by an integer. The size of the integer varies depending on the format. QImage supports several image formats described by the Format enum.
Monochrome images are stored using 1-bit indexes into a color table with at most two colors. There are two different types of monochrome images: big endian (MSB first) or little endian (LSB first) bit order.
...
The createAlphaMask() function builds and returns a 1-bpp mask from the alpha buffer in this image...
还有:
QImage::Format_MonoLSB --- 2 ---The image is stored using 1-bit per pixel. Bytes are packed with the less significant bit (LSB) first.
谁能帮我阐明如何将其转换为 cv::Mat。
此外,我是否应该读到每个像素都是一个 unsigned char
,或者我们将存储 8 个像素。
最佳答案
我已经成功地将单色 QImage 转换为 cv::Mat。我希望下面的代码对其他人有帮助:
重要编辑:此代码存在重大错误。 bytesPerLine
在某些机器上是字节对齐的,也是字对齐的。因此 width() 应该与 cur_byte 一起使用
QImage mask; //Input from wherever
cv::Mat workspace;
if(!mask.isNull() && mask.depth() == 1)
{
if(mask.width() != workspace.cols || mask.height() != workspace.rows)
workspace.create(mask.height(), mask.width(), CV_8UC1);
for(int i = 0; i < mask.height(); ++i)
{
unsigned char * cur_row = mask.scanLine(i);
//for(int cur_byte = 0, j = 0; cur_byte < mask.bytesPerLine(); ++cur_byte) wrong
for(int cur_byte = 0, j = 0; j < mask.width(); ++cur_byte)
{
unsigned char pixels = cur_row[cur_byte];
for(int cur_bit = 0; cur_bit < 8; ++cur_bit, ++j)
{
if(pixels & 0x01) //Least Significant Bit
workspace.at<unsigned char>(i, j) = 0xff;
else
workspace.at<unsigned char>(i, j) = 0x00;
pixels = pixels >> 1; //Least Significant Bit
}
}
}
}
关于c++ - 使用单色 QImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13754099/