2013-07-15 3 views
3

Мне нужно рассчитать стандартное отклонение изображения, которое у меня есть в объекте UIImage. Я уже знаю, как получить доступ ко всем пикселям изображения, по одному, поэтому как-то я могу это сделать. Мне интересно, есть ли где-то в рамках функции для выполнения этого более эффективным и эффективным способом ... Я не могу найти его, поэтому, возможно, он не существует. Кто-нибудь знает, как это сделать? byeстандартное отклонение UIImage/CGImage

+1

Вы должны написать его возможно, особенно учитывая, что это должно быть двумерное s tandard отклонение – MZimmerman6

ответ

4

Дальнейшее распространение на мой комментарий выше. Я определенно рассмотрю использование рамки Accelerate, особенно в зависимости от размера вашего изображения. Если изображение составляет несколько сотен пикселей на несколько сотен. У вас будет тонна данных для обработки, а Accelerate вместе с vDSP сделает всю эту математику намного быстрее, поскольку она обрабатывает все на графическом процессоре. Я посмотрю на это немного больше и, возможно, поставлю код за несколько минут.

UPDATE

Я буду размещать код, чтобы сделать стандартное отклонение в одном измерении с помощью 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 
+0

спасибо! это интересная отправная точка! Я попробую ... На самом деле я не знал рамки vDSP ... – ste72

+1

Да, это должно сработать нормально. Это просто формула для стандартного отклонения в одном измерении, поэтому вам нужно будет сделать векторный массаж, чтобы получить 2D-изображение в 1D, но кроме этого и, возможно, несколько опечаток в моем коде, вы должны быть хорошими. – MZimmerman6

2

Пожалуйста, объясните свой запрос так, чтобы может придумать конкретный ответ.

Если я получаю вас правильно, вы хотите рассчитать стандартное отклонение RGB пикселя или HSV цвета, вы можете создать собственный метод стандартного отклонения for circular quantities в случае HSV и RGB.

Мы можем сделать это, обернув значения. Например: Среднее значение [358, 2] градусов равно (358 + 2)/2 = 180 градусов. Но это неверно, потому что его среднее или среднее значение должно быть 0 градусов. Итак, мы завершаем 358 в -2. Теперь ответ равен 0. Итак, вам нужно применить упаковку, а затем вы можете рассчитать стандартное отклонение от ссылки выше.

UPDATE: Преобразование 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; 

}

+0

Привет Кришна! мое изображение - квадратная фотография. Мне нужно разделить его на несколько меньших квадратов, и мне нужен способ идентифицировать и удалить те меньшие квадраты, которые содержат только один однородный цвет ... по этой причине я думал о вычислении стандартного отклонения, чтобы определить threashold и dischard те под – ste72

+0

Вы можете рассчитать оттенок для всех пикселей малого квадрата, а затем рассчитать стандартное отклонение и установить пороговое значение в соответствии с вашей пригодностью (близко к нулю). значения оттенков [0, 360]. –

+0

спасибо вам большое! – ste72

Смежные вопросы