【发布时间】:2015-08-20 05:35:15
【问题描述】:
我正在尝试使用 opencv 实现 Matlab 函数 imquantize。我应该使用哪个opencv阈值函数来实现Matlab函数multithresh?完成阈值处理后,如何根据阈值标记像素?这是实施 imquantize 的正确方法吗?我应该在代码中包含任何其他功能吗?
【问题讨论】:
我正在尝试使用 opencv 实现 Matlab 函数 imquantize。我应该使用哪个opencv阈值函数来实现Matlab函数multithresh?完成阈值处理后,如何根据阈值标记像素?这是实施 imquantize 的正确方法吗?我应该在代码中包含任何其他功能吗?
【问题讨论】:
有一个基于 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);
【讨论】:
我想你正在寻找这样的东西
/*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 向量,可以为不同的通道提供不同的级别。
【讨论】: