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