在opencv中实现'imquantize'功能

时间:2015-08-20 05:35:16

标签: c++ matlab opencv

我正在尝试使用opencv实现Matlab函数的imquantize。哪个opencv阈值函数我应该用来实现matlab函数multithresh?一旦完成阈值处理,如何根据阈值标记像素?这是实施量化的正确方法吗?我应该在代码中包含其他任何功能吗?

2 个答案:

答案 0 :(得分:0)

有一个基于OpenCV here的实现,你可能应该明白这个想法:

cv::Mat
imquantize(const cv::Mat& in, const arma::fvec& thresholds) {
    BOOST_ASSERT_MSG(cv::DataType<float>::type == in.type(), "input is not of type float");

    cv::Mat index(in.size(), in.type(), cv::Scalar::all(1));
    for (int i = 0; i < thresholds.size() ; i++) {
        cv::Mat temp = (in > thresholds(i)) / 255;
        temp.convertTo(temp, cv::DataType<float>::type);
        index += temp;
    }

    return index;
}

已更新 thresholds是浮点阈值的向量(统一分布到# of levels,您要在[0, 1]内量化。 检查the code snippet如何使用它:

const float step = 1./levels[i];
arma::fvec thresh = arma::linspace<arma::fvec>(step, 1.-step, levels[i]-1);
channels[i] = imquantize(channels[i], thresh);

答案 1 :(得分:0)

我想你正在寻找类似的东西

    /*function imquantize
    * 'inputImage' is the input image.
    * 'levels' is an array of threholds
    * 'quantizedImage' is the reurned image  
    *  with quantized levels. 
    */
Mat imquantize(Mat inputImage, vector<vector<int> > levels)
{     
    //initialise output label matrix
    Mat quantizedImage(inputImage.size(), inputImage.type(), Scalar::all(1));    

    //Apply labels to the pixels according to the thresholds
    for (int i = 0; i < inputImage.cols; i++)
    {
        for (int j = 0; j < inputImage.rows; j++)
        {
            // Check if image is grayscale or BGR
            if(levels.size() == 1)
            {
                for (int k = 0; k < levels[0].size(); k++) 
                {
                    // if pixel < lowest threshold , then assign 0
                    if(inputImage.at<uchar>(j,i) <= levels[0][0])
                    { 
                        quantizedImage.at<uchar>(j,i) = 0;
                    }

                    // if pixel > highest threshold , then assign 255
                    else if(inputImage.at<uchar>(j,i) >= levels[0][levels[0].size()-1]) 
                    { 
                        quantizedImage.at<uchar>(j,i) = 255;
                    }

                    // Check the level borders for pixel and assign the corresponding
                    // upper bound quanta to the pixel
                    else
                    { 
                        if(levels[0][k] < inputImage.at<uchar>(j,i) && inputImage.at<uchar>(j,i) <= levels[0][k+1])
                        {
                            quantizedImage.at<uchar>(j,i) = (k+1)*255/(levels[0].size());
                        }
                    }
                }
            }

            else
            {
                Vec3b pair = inputImage.at<Vec3b>(j,i); 

                // Processing the Blue Channel
                for (int k = 0; k < levels[0].size(); k++) 
                {
                    if( pair.val[0] <= levels[0][0]) 
                    {
                        quantizedImage.at<Vec3b>(j,i)[0] = 0;
                    }
                    else if( pair.val[0] >= levels[0][levels.size()-1])
                    {
                        quantizedImage.at<Vec3b>(j,i)[0] = 255; 
                    } 
                    else
                    {
                        if(levels[0][k] < pair.val[0] && pair.val[0] <= levels[0][k+1]) 
                        {
                            quantizedImage.at<Vec3b>(j,i)[0] = (k+1)*255/(levels[0].size());
                        }
                    }
                }

                // Processing the Green Channel
                for (int k = 0; k < levels[1].size(); k++) 
                {
                    if( pair.val[1] <= levels[1][0]) 
                    {
                        quantizedImage.at<Vec3b>(j,i)[1] = 0;
                    }
                    else if( pair.val[1] >= levels[1][levels.size()-1])
                    {
                        quantizedImage.at<Vec3b>(j,i)[1] = 255; 
                    } 
                    else
                    {
                        if(levels[1][k] < pair.val[1] && pair.val[1] <= levels[1][k+1]) 
                        {
                            quantizedImage.at<Vec3b>(j,i)[1] = (k+1)*255/(levels[1].size());
                        }
                    }   
                }

                // Processing the Red Channel
                for (int k = 0; k < levels[2].size(); k++) 
                {
                    if( pair.val[2] <= levels[2][0]) 
                    {
                        quantizedImage.at<Vec3b>(j,i)[2] = 0;
                    }
                    else if( pair.val[2] >= levels[2][levels.size()-1])
                    {
                        quantizedImage.at<Vec3b>(j,i)[2] = 255; 
                    } 
                    else
                    {
                        if(levels[2][k] < pair.val[2] && pair.val[2] <= levels[2][k+1]) 
                        {
                            quantizedImage.at<Vec3b>(j,i)[2] = (k+1)*255/(levels[2].size());
                        }
                    }
                }
            }
        }
    }
    return quantizedImage;
}

在此函数中,输入必须是Mat :: Image和2D矢量,它们可以为不同的通道提供不同的级别。