UIImage/CGImage的标准偏差

3

我需要计算UIImage对象中图像的标准差。 我已经知道如何逐个访问图像的所有像素,因此可以进行计算。 我想知道是否在框架中有更好、更有效的函数来执行此操作...我找不到它,所以也许它不存在。 有人知道如何做吗? 再见


1
你可能需要自己编写代码,特别是考虑到这将是一个二维标准差。 - MZimmerman6
2个回答

4
进一步扩展我上面的评论。特别是根据您的图像大小,我肯定会考虑使用Accelerate框架。如果您的图像只有几百像素乘以数百像素,您将有大量数据需要处理,Accelerate以及vDSP将使所有这些数学计算更快,因为它在GPU上处理所有内容。我将进一步深入研究,并可能在几分钟内放置一些代码。 更新 我将发布一些代码,使用vDSP在单个维度上执行标准偏差,但这绝对可以扩展到2-D。
 float *imageR =  [0.1,0.2,0.3,0.4,...]; // vector of values
 int numValues = 100; // number of values in imageR
 float mean = 0; // place holder for mean
 vDSP_meanv(imageR,1,&mean,numValues); // find the mean of the vector
 mean = -1*mean // Invert mean so when we add it is actually subtraction
 float *subMeanVec  = (float*)calloc(numValues,sizeof(float)); // placeholder vector
 vDSP_vsadd(imageR,1,&mean,subMeanVec,1,numValues) // subtract mean from vector
 free(imageR); // free memory 
 float *squared = (float*)calloc(numValues,sizeof(float)); // placeholder for squared vector
 vDSP_vsq(subMeanVec,1,squared,1,numValues); // Square vector element by element
 free(subMeanVec); // free some memory
 float sum = 0; // place holder for sum
 vDSP_sve(squared,1,&sum,numValues); sum entire vector
 free(squared); // free squared vector
 float stdDev = sqrt(sum/numValues); // calculated std deviation

谢谢!这是一个有趣的起点!我会尝试...实际上我不知道vDSP框架... - ste72
1
没错,那应该可行。这直接是一维标准差的公式,因此您需要对向量进行一些处理,将您的二维图像转换为一维,除此之外,我的代码中可能会有一些错别字,但除此之外,您应该没问题。 - MZimmerman6

2
请解释您的查询,以便我们可以提供具体的回复。
如果我理解正确,您想要计算像素的RGB标准偏差或颜色的HSV标准偏差,您可以为HSV和RGB制定自己的标准偏差方法 用于圆形数量
我们可以通过包装值来实现这一点。 例如:[358, 2]度的平均值是(358 + 2)/ 2 = 180度。 但这是不正确的,因为其平均值或平均值应为0度。 所以我们将358包装成-2。 现在答案是0。 因此,您必须应用包装,然后可以从上面的链接计算标准偏差。
更新: 将RGB转换为HSV
    // r,g,b values are from 0 to 1 // h = [0,360], s = [0,1], v = [0,1]
//  if s == 0, then h = -1 (undefined)

void RGBtoHSV( float r, float g, float b, float *h, float *s, float *v )

{
 float min, max, delta;   
    min = MIN( r, MIN(g, b ));   
    max = MAX( r, MAX(g, b ));   
    *v = max;  
    delta = max - min;   
    if( max != 0 )  
        *s = delta / max;  
    else {   
        // r = g = b = 0   
        *s = 0;   
        *h = -1;   
        return; 
    }
    if( r == max )
        *h = ( g - b ) / delta; 
    else if( g == max )
        *h=2+(b-r)/delta;
    else 
        *h=4+(r-g)/delta; 
    *h *= 60;
    if( *h < 0 ) 
        *h += 360;
}

然后通过以下方式计算色调值的标准差:

double calcStddev(ArrayList<Double> angles){
  double sin = 0;
  double cos = 0;
  for(int i = 0; i < angles.size(); i++){
       sin += Math.sin(angles.get(i) * (Math.PI/180.0));
       cos += Math.cos(angles.get(i) * (Math.PI/180.0)); 
  }
  sin /= angles.size();
  cos /= angles.size();

  double stddev = Math.sqrt(-Math.log(sin*sin+cos*cos));

  return stddev;

}


嗨Krishna!我的图片是一个正方形的照片。我需要将它分成几个小正方形,并且需要一种方法来识别和删除那些只包含单一颜色的小正方形...因此,我考虑计算标准差以定义阈值并丢弃那些低于阈值的小正方形。 - ste72
你可以计算小正方形中所有像素的色调,然后计算标准差,并根据你的需要设置阈值(接近零)。色调值范围为[0, 360]。 - Krishna Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接