UIImage / CGImage的标准偏差

时间:2013-07-15 12:47:31

标签: ios uiimage standard-deviation

我需要计算UIImage对象内部图像的标准偏差。 我已经知道如何一次一个地访问图像的所有像素,所以不知怎的,我可以做到。 我想知道框架中是否存在一个以更好,更有效的方式执行此操作的功能......我找不到它,所以它可能不存在。 有谁知道怎么做? 再见

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

请解释您的查询,以便能够提出具体的答复。

如果我找到了你想要计算像素的RGB或颜色的HSV的标准偏差,你可以在HSV和RGB的情况下构建你自己的标准偏差方法for circular quantities

我们可以通过包装值来实现。 例如:[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;

}