opencv中'imquantize'函数的实现

Posted

技术标签:

【中文标题】opencv中\'imquantize\'函数的实现【英文标题】:Implementation of 'imquantize' function in opencvopencv中'imquantize'函数的实现 【发布时间】:2015-08-20 05:35:15 【问题描述】:

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

【问题讨论】:

【参考方案1】:

有一个基于 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 是浮点阈值的向量(均匀分布到您要在[0, 1] 内量化的# of levels)。 检查@ 987654322@如何使用:

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);

【讨论】:

很抱歉问你。我从哪里得到这个“门槛”? 'thresholds' 是一个 n 乘 1 矩阵。这样对吗?我怎样才能制作这个矩阵? @user3440725 我已经更新了答案以使其清楚。 @herohuyongato:我认为“级别”是个位数。但这里是一个向量,对吧?你能给我举个'level'值的例子吗?【参考方案2】:

我想你正在寻找这样的东西

    /*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 向量,可以为不同的通道提供不同的级别。

【讨论】:

以上是关于opencv中'imquantize'函数的实现的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV中导向滤波介绍与应用

opencv-python下简单KNN分类识别

opencv python 可以读取是屁mov文件吗

python-应用OpenCV和Python进行SIFT算法的实现

opencv的频域滤波

源码阅读opencv中opencl版本的dft函数的实现细节