简体   繁体   English

UIImage / CGImage的标准偏差

[英]standard deviation of a UIImage/CGImage

I need to calculate the standard deviation on an image I have inside a UIImage object. 我需要计算UIImage对象内部图像的标准偏差。 I know already how to access all pixels of an image, one at a time, so somehow I can do it. 我已经知道如何一次一个地访问图像的所有像素,所以不知怎的,我可以做到。 I'm wondering if there is somewhere in the framework a function to perform this in a better and more efficient way... I can't find it so maybe it doensn't exist. 我想知道框架中是否存在一个以更好,更有效的方式执行此操作的功能......我找不到它,所以它可能不存在。 Do anyone know how to do this? 有谁知道怎么做? bye 再见

To further expand on my comment above. 进一步扩展我上面的评论。 I would definitely look into using the Accelerate framework, especially depending on the size of your image. 我肯定会考虑使用Accelerate框架,特别是取决于图像的大小。 If you image is a few hundred pixels by a few hundred. 如果你的图像是几百像素几百。 You will have a ton of data to process and Accelerate along with vDSP will make all of that math a lot faster since it processes everything on the GPU. 您将需要处理大量数据,并且与vDSP一起Accelerate将使所有数学运算更快,因为它处理GPU上的所有内容。 I will look into this a little more, and possibly put some code in a few minutes. 我会再研究一下这个问题,并且可能会在几分钟内完成一些代码。

UPDATE UPDATE

I will post some code to do standard deviation in a single dimension using vDSP , but this could definitely be extended to 2-D 我将发布一些代码,使用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

Please explain your query so that can come up with specific reply. 请解释您的查询,以便能够提出具体的答复。

If I am getting you right then you want to calculate standard deviation of RGB of pixel or HSV of color, you can frame your own method of standard deviation for circular quantities in case of HSV and RGB. 如果我得到你的权利,你要计算像素的RGB或颜色的HSV的标准偏差,您可以框住自己的标准偏差的方法为圆形的数量在HSV和RGB的情况。

We can do this by wrapping the values. 我们可以通过包装值来实现。 For example: Average of [358, 2] degrees is (358+2)/2=180 degrees. 例如:[358,2]度的平均值是(358 + 2)/ 2 = 180度。 But this is not correct because its average or mean should be 0 degrees. 但这不正确,因为它的平均值或平均值应为0度。 So we wrap 358 into -2. 所以我们将358包装成-2。 Now the answer is 0. So you have to apply wrapping and then you can calculate standard deviation from above link. 现在答案是0.所以你必须应用包装,然后你可以从上面的链接计算标准偏差。

UPDATE: Convert RGB to HSV 更新:将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;
}

and then calculate standard deviation for hue value by this: 然后计算色调值的标准偏差:

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;

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM