Opencv 通道分离与合并 split() merge()
我有一个梦想,我写的代码,可以像诗一样优美。我有一个梦想,我做的设计,能恰到好处,既不过度,也无不足。
opencv 提供了split()函数和merge()函数,目的是将一个多通道数组分离成几个单通道数组以及将几个数组合并成为一个数组。
此函数相对简单,主要了解OPencv的彩色空间顺序为:蓝绿红, 以及相关参数的要求即可。
下面将简单演示:
//ps: 为方便演示,以下数组深度均为CV_8U
void mySplit(Mat mat, std::vector<Mat> &matVec)
{
if (!mat.data || mat.type() != CV_8UC3)
{
return;
}
int channels = mat.channels();
matVec.clear();
for (int i = 0; i < channels; i++)
{
Mat mat1(mat.size(), CV_8UC1);
matVec.push_back(mat1);
}
for (int i = 0; i < mat.rows; i++)
{
for (int j = 0; j < mat.cols; j++)
{
for (int n = 0; n < channels; n++)
{
matVec[n].at<uchar>(i, j) = mat.at<Vec3b>(i, j)[n];
}
}
}
}
void myMerge(Mat& mat, std::vector<Mat> &matVec)
{
if (matVec.empty())
{
return;
}
for (int i = 0; i < matVec.size(); i++)
{
if (matVec.at(i).channels() != 1 || matVec.at(i).type() != CV_8UC1)
{
return;
}
}
mat.create(matVec.at(0).size(), CV_8UC3);
for (int i = 0; i < mat.rows; i++)
{
for (int j = 0; j < mat.cols; j++)
{
for (int n = 0; n < matVec.size(); n++)
{
mat.at<Vec3b>(i, j)[n] = matVec[n].at<uchar>(i, j);
}
}
}
}
int main()
{
Mat mat(5, 5, CV_8UC3);
randu(mat, Scalar(0), Scalar(255));
std::vector<Mat> matVec1, matVec2;
split(mat, matVec1);
mySplit(mat, matVec2);
if (matVec2.empty())
{
return -1;
}
Mat temp1 = matVec1[0] - matVec2[0];
Mat temp2 = matVec1[1] - matVec2[1];
Mat temp3 = matVec1[2] - matVec2[2];
cout << temp1 << endl;
cout << temp2 << endl;
cout << temp3 << endl;
Mat mat2, mat3;
merge(matVec1, mat2);
myMerge(mat3, matVec2);
Mat temp = mat2 - mat3;
cout << temp << endl;
getchar();
return 0;
}
运行结果:
[ 0, 0, 0, 0, 0;
0, 0, 0, 0, 0;
0, 0, 0, 0, 0;
0, 0, 0, 0, 0;
0, 0, 0, 0, 0]
[ 0, 0, 0, 0, 0;
0, 0, 0, 0, 0;
0, 0, 0, 0, 0;
0, 0, 0, 0, 0;
0, 0, 0, 0, 0]
[ 0, 0, 0, 0, 0;
0, 0, 0, 0, 0;
0, 0, 0, 0, 0;
0, 0, 0, 0, 0;
0, 0, 0, 0, 0]
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]