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'函数的实现的主要内容,如果未能解决你的问题,请参考以下文章