3

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

4

2 回答 2

4

进一步扩展我上面的评论。我肯定会考虑使用该Accelerate框架,尤其是取决于图像的大小。如果你的图像是几百像素乘几百。您将有大量数据要处理,并且由于它在 GPU 上Accelerate处理vDSP所有内容,因此所有这些数学运算都会变得更快。我将对此进行更多研究,并可能在几分钟内输入一些代码。

更新

我将发布一些代码来使用 在一维中进行标准偏差vDSP,但这绝对可以扩展到二维

 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
于 2013-07-15T13:01:36.013 回答
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;

}

于 2013-07-15T13:23:00.550 回答