Нужно преобразовать значение RGB в систему XYZ, затем на диаграмме xy (цветовой локус, CIE 1931) провести луч из точки белого (для заданого источника света A, C, D65...) через заданую точку xy. Точка пересечения луча с кривой спектральных цветов даст доминирующую длину волны. Для пурпурных цветов луч проводится в противоположную сторону. Обычно для них ставится штрих у лямбды. С програмной точки зрения можно использовать сплайны. Литература: Джадд, Вышецки.
Контуры не нужны. Просто преобразуете картинку в черно-белый формат, так чтобы объект был белым, а фон - черным. Далее вызываете функцию cv2.fitLine, из ее результатов берете арктангенс и все, угол получен.
Делается все буквально за три команды.
1. Закрытие с помощью cv2.morphologyEx, ядро квадратное, размерами в 2 раза меньше квадратов. Удаляются одиночные квадраты.
2. инверсия. cv2.bitwise_not
3. cv2.connectedComponents подсчет оставшихся объединенных квадратов.
Если надо выделить отдельные квадраты в объединении, то используйте после п.1 cv2. matchTemplate
У вас в уравнении две переменные, а не одна, тета и фи. Тут нужны скорее цилиндрические координаты. Или изолинии. По сути это будет набор спиралей, вдоль оси фи с радиусом равным множителям до экспоненты ( если тета это параметр).
Формулу можно сократить, если использовать 0.5*sin(2x)=sin(x)*cos(x)