我最近开始用OpenCV操作图像。
据我所知,cv :: max(input1,input2,output)用于查找2个图像的最大BGR值。我想在一个颜色通道内最大化,请参阅以下2 BGR垫(垫尺寸2x2)的示例:
input1= [110, 100, 90, 109, 99, 89;
111, 99, 89, 108, 98, 88]
inout2= [97, 141, 158, 95, 138, 157;
98, 149, 169, 97, 148, 168]
我想最大化蓝色通道中的值,因此我将输出绿色和红色通道的任何值;因此我希望结果如下:
output= [110, 100, 90, 109, 99, 89;
111, 99, 89, 108, 98, 88]
是的,输出mat正好是input1的副本,但请注意运行
cv::max(input1, input2, output);
给出
output= [110, 141, 158, 109, 138, 157;
111, 149, 169, 108, 148, 168]
以某种方式混合2个垫子通道。
很抱歉写这么久;我只是想清楚。谢谢,,,
更新:我已经使用C ++ for循环实现了一个解决方案。老实说他们工作但我正在寻找更快更简单的东西,如果有的话。
UPDATE2:从2个输入图像中,我需要来自蓝色通道的最大值,并将其存储到输出中,并带有相关的绿色和红色值。
答案 0 :(得分:0)
您可以分割图像,计算所需通道的最大值,然后将其合并到输出数组中。并不简单,但我认为它比传统的for循环方法更好。在有限的时间内,这就是我写的,它可以按你的意愿工作。
int ssz[2] = {2,2};
double data1[12] = {110,100,90,109,99,89,111,99,89,108,98,88};
double data2[12] = {120,141,158,95,138,157,98,149,169,97,148,168};
Mat in1(2,ssz,CV_64FC3,data1);
Mat in2(2,ssz,CV_64FC3,data2);
Mat out = in1.clone();
Mat c1[3]; //0 indexes will be blue channel
Mat c2[3];
Mat oc[3];
split(in1,c1);
split(in2,c2);
split(out,oc);
cv::max(c1[0],c2[0],oc[0]);
cv::merge(oc,3,out);
要看到它有效,我将input2的第一个元素更改为120.我测试并去除了它,它有效。
答案 1 :(得分:0)
我使用经典的C ++ for循环制作了这个,这就是我的所有优点:D但是,我仍然希望至少在避免.at
方面有更好的答案。
int imdepth=CV_32F;
Mat outBlue (2, 2, imdepth);
Mat outGreen (2, 2, imdepth);
Mat outRed (2, 2, imdepth);
for (int i=0; i<2; i++) {
for (int j=0; j<2; j++) {
float blue1 = in1b.at<float>(i,j); //in1b, in2b, in1g, etc. are
float blue2 = in2b.at<float>(i,j); //channels from img1 and img2
if (blue1>blue2) {
outBlue.at<float>(i,j) = blue1;
outGreen.at<float>(i,j) = in1g.at<float>(i,j);
outRed.at<float>(i,j) = in1r.at<float>(i,j);
} else {
outBlue.at<float>(i,j) = blue2;
outGreen.at<float>(i,j) = in2g.at<float>(i,j);
outRed.at<float>(i,j) = in2r.at<float>(i,j);
}
}
}
vector<Mat> out(3);
out[0] = outBlue;
out[1] = outGreen;
out[2] = outRed;
Mat output (2, 2, CV_32FC3);
merge (out, output);