如何使用OpenCV从栅格波段获取图像?

时间:2018-03-02 21:04:42

标签: opencv

我有不同的光栅波段,我需要使用OpenCV从这些波段中获取正确的图像。怎么办呢?

2 个答案:

答案 0 :(得分:0)

我不喜欢编写所有代码并像通常那样对其进行测试,所以我只想简要介绍一种方法。

假设您的图像在维度上是WIDTHxHEIGHT,并且由连续写入的无符号字符数据组成,而不填充到名为<div id="text" onclick="random()"> </div> <button id="green" onclick="incrementA()">A </button> <button id="green" onclick="incrementB()">B </button> <button id="green" onclick="incrementC()">C </button>band1.dat等的文件中。

band2.dat

答案 1 :(得分:0)

作为我的另一个答案的替代方案,您可以在原始文件上放置一个小的ASCII标头,使其成为PGM文件, OpenCV 可以在没有任何额外库的情况下本地读取。 PGM格式是{strong> NetPBM 套件中here on Wikipedia所述的一部分。

因此,假设您的每个栅格都是单通道,8位图像,尺寸为100像素宽,256像素高。将每个波段变为终端中的PGM图像:

{ printf "P5\n100 256\n255\n"; cat band1.dat; } > band1.pgm
{ printf "P5\n100 256\n255\n"; cat band2.dat; } > band2.pgm
{ printf "P5\n100 256\n255\n"; cat band3.dat; } > band3.pgm
{ printf "P5\n100 256\n255\n"; cat band4.dat; } > band4.pgm

现在您可以使用 GIMP feh 查看4个灰度图像,更重要的是 OpenCV 可以读取的图像。所以你的代码变成了:

Mat b1 = imread("band1.pgm", IMREAD_UNCHANGED);
Mat b2 = imread("band2.pgm", IMREAD_UNCHANGED);
Mat b3 = imread("band3.pgm", IMREAD_UNCHANGED);
Mat b4 = imread("band4.pgm", IMREAD_UNCHANGED);

// Now merge
auto channels = std::vector<cv::Mat>{b1, b2, b3, b4};
cv::Mat FourBandBoy;
cv::merge(channels, FourBandBoy);

由于您没有提供任何样本光栅图像,我制作了4张图像,每张100x256,以便快速演示。他们在这里:

-rw-r--r--  1 mark  staff  25600 21 Mar 10:44 band1.dat
-rw-r--r--  1 mark  staff  25600 21 Mar 10:44 band2.dat
-rw-r--r--  1 mark  staff  25600 21 Mar 10:44 band3.dat
-rw-r--r--  1 mark  staff  25600 21 Mar 10:44 band4.dat

希望您可以从尺寸中看出它们是100x256,单通道和8位。

我按照原始说明将它们转换为PGM:

{ printf "P5\n100 256\n255\n"; cat band1.dat; } > band1.pgm
{ printf "P5\n100 256\n255\n"; cat band2.dat; } > band2.pgm
{ printf "P5\n100 256\n255\n"; cat band3.dat; } > band3.pgm
{ printf "P5\n100 256\n255\n"; cat band4.dat; } > band4.pgm

给出:

-rw-r--r--  1 mark  staff  25615 21 Mar 10:44 band1.pgm
-rw-r--r--  1 mark  staff  25615 21 Mar 10:44 band2.pgm
-rw-r--r--  1 mark  staff  25615 21 Mar 10:44 band3.pgm
-rw-r--r--  1 mark  staff  25615 21 Mar 10:44 band4.pgm

因此,您可以看到PGM标头总数为15个字节。图像现在看起来像这样:

enter image description here enter image description here enter image description here enter image description here

我稍微修改了代码:

#include <iostream>
#include <opencv2/opencv.hpp>
#include <cstdio>

using namespace cv;
using namespace std;

int
main(int argc,char*argv[])
{
   Mat b1 = imread("band1.pgm", IMREAD_UNCHANGED);
   Mat b2 = imread("band2.pgm", IMREAD_UNCHANGED);
   Mat b3 = imread("band3.pgm", IMREAD_UNCHANGED);
   Mat b4 = imread("band4.pgm", IMREAD_UNCHANGED);

   // Now merge
   auto channels = std::vector<cv::Mat>{b1,b2,b3,b4};
   cv::Mat BigBoy;
   cv::merge(channels, BigBoy);

   // Save
   cv::imwrite("result.png",BigBoy);
}

结果......

enter image description here

希望您能看到生成的图像:

  • 是蓝色,其中band1中有很多白色,
  • 是绿色,其中band2中有很多白色,
  • 是红色,其中band3为白色
  • 是透明的,其中带4是黑色的