我想创建自己的SetChannel
函数,该函数将设置图像的特定通道。例如,我有一个类型为input
的图像CV_16UC3
(类型为ushort
的BGR图像),我想将绿色通道(由于从零开始的索引,其值= 1)更改为{ ushort
的{1}}值。为此,我调用32768
。
SetChannel(input,1,32768)
与嵌套循环相比,我更喜欢在单个循环中工作,因此如上所述,我定义了迭代次数template<typename T>
void SetChannel(Mat mat, uint channel, T value)
{
const uint channels = mat.channels();
if (channel + 1 > channels)
return;
T * data = (T*)mat.data;
// MBPR : number of Memory Block Per Row
// Mat.step : number of byte per row
// Mat.elemSize1() : number of byte per channel
const unsigned int MBPR = mat.step / mat.elemSize1();
// N : total number of memory blocks
const unsigned int N = mat.rows * MBPR;
for (uint i = channel; i < N; i += channels)
data[i] = value;
}
。
上面的代码按预期工作,但是其他一些人说了这一部分
N
是一种代码味道,被认为是设计不良的程序。
现在,我想用另一种方法重写新的方法,如下所示。
它无法正常工作,因为我不知道如何将T * data = (T*)mat.data;
分配给类型T value
的{{1}}。
data[i]
如何将uchar
类型的template<typename T>
void SetChannel(Mat mat, uint channel, T value)
{
const uint channels = mat.channels();
if (channel + 1 > channels)
return;
uchar * data = mat.data;
const unsigned int N = mat.rows * mat.step;// byte per image
const unsigned int bpc = mat.elemSize1();// byte per channel
const unsigned int bpp = mat.elemSize(); // byte per pixel
for (uint i = channel * bpc; i < N; i += bpp)
//data[i] = value;
}
分配给value
类型的T
而不造成任何损失?
对于那些不了解data[i]
的人,以下内容可能会有用。
uchar
类OpenCV提供了一堆图像。例如,
Mat
代表灰度图像类型,其中每个像素具有一个类型为Mat
的通道。CV_8UC1
代表BGR(不是RGB)图像类型,其中每个像素具有三个通道,每个通道类型为uchar
。 CV_8UC3
代表BGR(非RGB)图像类型,其中每个像素具有三个通道,每个通道的类型为uchar
。
等。
CV_16UC3
是封装图像的类。它具有几个属性和功能。让我列出其中一些我将在此问题中使用的内容,以便您可以更好地理解我的情况。
ushort
:类型为Mat
的指针,指向一个图像像素块。Mat.data
:行数uchar
:每像素的通道数Mat.rows
(以1结尾):每个通道的字节数Mat.channels()
:每个像素的字节数。
Mat.elemSize1()
。Mat.elemSize()
:每行字节数这里Mat.elemSize() = Mat.channels() * Mat.elemSize1()
被认为是
-每行“有效”像素数(我将其命名为EPPR),
-每个像素或Mat.step
的通道数,以及
-每个通道或Mat.step
的字节数。
在数学上,
Mat.channels()
让我将Mat.elemSize1()
定义为每行( Mat.step = EPPR * Mat.elemSize()
Mat.step = EPPR * Mat.channels() * Mat.elemSize1()
)的存储块。如果您知道EPPR * Mat.channels()
的正确术语,请告诉我。
因此,MBPR
。
答案 0 :(得分:0)
我是从离线用户那里获得的。希望它对其他人也有用。
template<typename T>
void SetChannel(Mat mat, uint channel, T value)
{
const uint channels = mat.channels();
if (channel + 1 > channels)
return;
uchar * data = mat.data;
const unsigned int N = mat.rows * mat.step;// byte per image
const unsigned int bpc = mat.elemSize1();// byte per channel
const unsigned int bpp = mat.elemSize(); // byte per pixel
const unsigned int bpu = CHAR_BIT * sizeof(uchar);// bits per uchar
for (uint i = channel * bpc; i < N; i += bpp)
for (uint j = 0; j < bpc; j++)
data[i + j] = value >> bpu * j;
}