Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Computing max values and channel indices pixel-wise

Given a cv::Mat input with n-channels, I want to recieve the max channel value of each pixel in one cv::mat out_val and in another cv::Mat out_idx the channel index of the maximum value, again of each pixel. So at the end input.size() = out.idx.size() = out_val.size(). Furthermore, if various channels have the same max value, a random channel index should be saved in the out_idx. So, you could do this with several for-loops, looping over each pixel and then comparing each channel value and so on. But I wanted to do this with kind of matrix operations to be more efficient. So I came up with something like the attached code. However, there is still missing the random choice for several maximum values and for sure there is a nicer coding instead of all these help matrices. So the question is: How to implement my task in a more efficient way (1) and adding the random idx choice (2)

std::vector<cv::Mat> tmp_ch;
cv::split(input, tmp_ch);

out_idx = cv::Mat::zeros(input.size().height, input.size().width, CV_32SC1);
out_val = cv::Mat::zeros(input.size().height, input.size().width, CV_64FC1);

for(int i = 0; i < tmp_ch.size(); i++) {

    cv::Mat bin = out_val < tmp_ch.at(i); // 0 -> old value stays; 255 -> update value in out_*
    cv::Mat buff_ch, buff_max, buff_idx, curr_idx;

    out_val.copyTo(buff_max, 255-bin);
    tmp_ch.at(i).copyTo(buff_ch, bin);

    cv::add(buff_max, buff_ch, out_val);

    curr_idx = cv::Mat(input.size().height, input.size().width, CV_32SC1, cv::Scalar(i));
    curr_idx.copyTo(curr_idx, bin);
    out_idx.copyTo(buff_idx, 255-bin);

    cv::add(out_idx,curr_idx,out_idx);
}

Thanks for your help!!!