【问题标题】:What is the Emgu CV equivalent of the Open CV saturate_cast function?什么是 Open CV saturate_cast 函数的 Emgu CV 等效项?
【发布时间】:2013-01-22 11:59:16
【问题描述】:

问题

emgucv 中的saturate_cast 是什么?

背景

我有一个Image<Bgr, byte>,我想对其中的每个像素执行一个简单的计算(顺便说一句:alpha * val + beta 其中alphabeta 被传入)。要在C++ 中执行此操作,我可以执行此操作:

cv::Mat new_image = cv::Mat::zeros(image.size(), image.type());
for (int y = 0; y < image.rows; y++)
{ 
    for (int x = 0; x < image.cols; x++)
    { 
        for (int c = 0; c < 3; c++)
        {
            new_image.at<cv::Vec3b>(y,x)[c] = cv::saturate_cast<uchar>(
                alpha * (image.at<cv::Vec3b>(y,x)[c]) + beta);
        }
    }
}

在 Emgu CV 中执行相同操作的一个非常缓慢的方法是:

var newImage = image.CopyBlank();
for (int y = 0; y < image.Rows; y++)
{
    for (int x = 0; x < image.Cols; x++)
    {
        MCvScalar orig = image[y, x].MCvScalar;            
        var v0 = alpha * orig.v0 + beta;
        var v1 = alpha * orig.v1 + beta;
        var v2 = alpha * orig.v2 + beta;
        var v3 = alpha * orig.v3 + beta;
        var newCol = new Bgr();
        newCol.MCvScalar = new MCvScalar(v0, v1, v2, v3);
        newImage[y, x] = newCol;
    }
}

但这只是,正如我所说,非常慢(太慢),所以我 read 应该使用 Data 属性,所以我可以做这样的事情:

var data = image.Data;
var newImage = image.CopyBlank();
for (int y = 0; y < image.Rows; y++)
{
    for (int x = 0; x < image.Cols; x++)
    {
        for (int c = 0; c < 3; c++)
        {
            var b = data[y, x, c];
            double ret = alpha * b + beta;      

            // Eek, now I need to saturate_cast...                          
            newImage.Data[y, x, c] = (byte)ret;
        }
    }
}

但这并不正确,因为我只是将double 转换为byte 而没有执行saturate_cast

我也可以使用Convert 泛型方法,我更喜欢这种方法,但问题是一样的——我有一个byte,我应用我的计算并有一个double,但我需要回byte

【问题讨论】:

    标签: c# .net opencv emgucv


    【解决方案1】:

    我最终编写了自己的方法,因为我认为emgu cv 中没有任何预先设置的内容。

    基于saturate_cast 的文档,我认为(因为它与我尝试过的图像产生相同的结果)相当于c# 中的saturate_cast 是: p>

    private static byte SaturateCast(double value)
    {
        var rounded = Math.Round(value, 0);
    
        if (rounded < byte.MinValue)
        {
            return byte.MinValue;
        }
    
        if (rounded > byte.MaxValue)
        {
            return byte.MaxValue;
        }
    
        return (byte)rounded;
    }
    

    所以就我而言,我可以做到这一点,我认为这非常优雅(并且比我原来的方法快得多):

    var newImage = image.Convert(b => SaturateCast(alpha * b + beta));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-05
      • 1970-01-01
      • 2012-07-15
      相关资源
      最近更新 更多