OpenCV:处理 12 位灰度原始数据



过去我使用OpenCv处理32位.bmp文件,并取得了成功的结果。如何使用 Opencv 函数来处理 12 位原始数据?我的处理主要是一些操作,例如查找一些 1000 像素等。

编辑我得到的文件是.bin文件。 图像中的像素是这样放置的(文件包含这样的所有内容,因为我正在拍摄白纸的照片):

(FF)(0F)(FF)(0F)(FF)(0F)(FF)(0F)(FF)(0F)(FF)(0F)(FF)(0F)

显然,我可以对此进行 16 位处理。

我想对这张图像进行 16 位处理。然后,这个秘密被揭示在另一个问题中。

对于 16 位,我将不得不切换到 PNG 而不是 bmp!

这个文档说我可以在OpenCV中使用16位PNG

据我所知,OpenCV 只能正确处理 8、16 和 32 位图像。

根据你想做什么,你应该

    将 12 位图像
  • 转换为 8 位图像(假设它是 12 位拜耳编码的图像)
  • 或者通过用零填充值来手动将其转换为 16。从我在这里发现的情况来看,这可能已经在您的图像上完成。

我建议您在执行任何操作之前仔细观察像素在图像中的确切位置。这将极大地帮助您了解什么是最好的。一个好方法是使用 bless 或其他十六进制编辑器

编辑:

从这里开始,您的数据(我认为)用填充编码超过 16 位

使用 Opencv 简单地从 16 位转换为 8 位应该可以解决问题,因为这是转换为 JPEG 时所做的。你至少试过吗?

左移位并将它们存储为 16 位。

对于黑白相机:

cv::Mat imgOpenCV = cv::Mat(cv::Size(img->width, img->height), CV_16UC1, (char*)img->imageData, cv::Mat::AUTO_STEP); //Convert the raw image
imgOpenCV.convertTo(imgOpenCV, CV_16UC1, 1.0*(2^4), 0.0); //Shift left 4 bits

对于彩色相机:

// Convert the image using the manufacturer's SDK (Imperx in this case)
IpxImage* imgConverted = nullptr;
IpxError err = IPX_CAM_ERR_OK;
IpxSize imgSize;
imgSize.height = img->height;
imgSize.width = img->width;
uint32_t pixelType = II_PIX_BGR12;
err = IpxCreateImage(&imgConverted, imgSize, pixelType);
err = IpxBayer_ConvertImage(hBayer, img, imgConverted);
// Create OpenCV converted image
cv::Mat imgOpenCV = cv::Mat(cv::Size(imgConverted->width, imgConverted->height), CV_16UC3, (char*)imgConverted->imageData, cv::Mat::AUTO_STEP); //Convert the image
imgOpenCV.convertTo(imgOpenCV, CV_16UC3, 1.0*(2^4), 0.0); //Shift left 4 bits

您也可以使用制造商的 SDK 直接转换为 16 位,但我怀疑这会缩放位深度,而不是在某些情况下移动它。 我宁愿保留原始位深度信息,因此自己进行转换可以防止我在更换制造商时不得不查看引擎盖下(不幸的是,GigE相机迫使您使用制造商SDK)。

OpenCV的任何功能都不支持12位数据。

将数据读取为"char"。3 个字符 = 2x12 位数据。此数据可以方便地转换为 16 位数据:

  1. 将字符 1 左移 4 并存储为 short1。
  2. 将其与 (char2 & 0xF0) 相加,即可获得 short1 中的前 12 位数据。
  3. 左移(char2 & 0x0F)按 8 并存储到 short2。
  4. 用 char3 添加它以获得 short2 中的下一个 12 位数据。

最新更新