Алгоритм с C++ на Python (преобразование радиальной симметрии)

Мне нужно преобразовать алгоритм преобразования радиальной симметрии с C++ на Python. Я новичок в Python и никогда не использовал C++.

void RadSymTransform(InputArray gradx,InputArray grady,OutputArray result,int ray,double minval=0,double maxval=255)
{
Mat gxMat=gradx.getMat();
Mat gyMat=grady.getMat();
result.create(gradx.size(), CV_16UC1);
Mat resMat=result.getMat();
resMat=Mat::zeros(resMat.size(), resMat.type());
int x,y,i,H,W;
double tx,ty,gx,gy,ampl,max;
H=gxMat.rows;W=gxMat.cols;
for(y=0;y<H;y++)
    for (x = 0; x < W; x++)
    {
        gx=gxMat.at<double>(y,x);
        gy=gyMat.at<double>(y,x);
        ampl=sqrt(gx*gx+gy*gy);
        if ((ampl>minval)&&(ampl<maxval)){
            max=(abs(gx)>abs(gy)?abs(gx):abs(gy));
            gx/=max;gy/=max;
            tx=x-ray*gx;ty=y-ray*gy;
            if (tx<0||tx>W||ty<0||ty>H)continue;
            tx=x;ty=y;
            for (i = 0; i < ray; ++i)
            {
                tx-=gx;ty-=gy;
                resMat.at<ushort>((int)ty,(int)tx)++;
            }
        }
    }
}

Он принимает градиенты x и y и радиус обнаружения (луч). minval и maxval - это нижний и верхний пороги градиента.

Алгоритм должен преобразовать изображение монеты внизу в преобразование радиальной симметрии.

Алгоритм с C++ на Python (преобразование радиальной симметрии)Алгоритм с C++ на Python (преобразование радиальной симметрии)

Это моя версия на Python, но, к сожалению, я получаю сообщение об ошибке:

Traceback (most recent call last):
  File "C:/Users/Christian/PycharmProjects/symmetry_transform4/RadSymTransform.py", line 74, in <module>
    print(radSymTransform(gray, 60, 0, 255))
  File "C:/Users/Christian/PycharmProjects/symmetry_transform4/RadSymTransform.py", line 64, in radSymTransform
    result[ty, tx] = result[ty, tx] + 1
IndexError: index 1024 is out of bounds for axis 1 with size 1024

код:

import cv2
import cv2
import numpy as np
import math


# x gradient
def gradx(img):
    img = img.astype('int')
    rows, cols = img.shape
    # Use hstack to add back in the columns that were dropped as zeros
    return np.hstack((np.zeros((rows, 1)), (img[:, 2:] - img[:, :-2]) / 2.0, np.zeros((rows, 1))))


# y gradient
def grady(img):
    img = img.astype('int')
    rows, cols = img.shape
    # Use vstack to add back the rows that were dropped as zeros
    return np.vstack((np.zeros((1, cols)), (img[2:, :] - img[:-2, :]) / 2.0, np.zeros((1, cols))))


# img -> gray-scale image
# Detection radius ray
# minVal -> low threshold for the gradient
# maxVal -> low threshold for the gradient
def radSymTransform(img, ray, minVal, maxVal):
    #gxMat = gradx(img)
    #gyMat = grady(img)

    gxMat = cv2.Sobel(img,cv2.CV_64F, 1, 0, ksize=5)
    gyMat = cv2.Sobel(img,cv2.CV_64F, 0, 1, ksize=5)

    gxMatShape = gradx(img).shape

    result = np.zeros(img.shape)
    # test = vGradx.getMat()

    # image height = number of rows
    # image width = number of columns
    height = gxMatShape[0]
    width = gxMatShape[1]

    y = 0  # counter 1: y-coordinate
    x = 0  # counter 2: x-coordinate

    while y < height:
        while x < width:
            gx = gxMat[y, x]
            gy = gyMat[y, x]
            ampl = math.sqrt(gx * gx + gy * gy)

            if ampl > minVal and ampl < maxVal:
                maxXY = max(abs(gx), abs(gy))
                gx = gx / maxXY
                gy = gy / maxXY
                tx = x - ray * gx
                ty = y - ray * gy
                if tx < 0 or tx > width or ty < 0 or ty > width:
                    tx = x
                    ty = y

                i = 0  # counter 3
                while i < ray:
                    tx = int(tx - gx)
                    ty = int(ty - gy)
                    # Increment result at position (tx,ty)
                    if tx < width and ty < height:
                        result[ty, tx] = result[ty, tx] + 1
                    i = i + 1
            x = x + 1
        x = 0
        y = y + 1

    return result


img = cv2.imread('data/P1190263.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

result = radSymTransform(gray, 60, 0, 255)
print(result)
cv2.imshow("Output:", result)
cv2.waitKey(0)

Буду признателен за любой совет, что я сделал не так.

Редактировать: Я только что добавил условие, что нельзя выходить за границы, но выход слишком высокий, это означает просто белое изображение:

Алгоритм с C++ на Python (преобразование радиальной симметрии)

Изменить 2: Я изменил параметры на radSymTransform(gray, 1, 250, 255) (первый) и radSymTransform(gray, 10, 250, 255) (второй) и получил этот вывод, который тоже не очень хорош:

Алгоритм с C++ на Python (преобразование радиальной симметрии)Алгоритм с C++ на Python (преобразование радиальной симметрии)

Было бы полезно сообщить нам, какая строка кода вызывает эту ошибку, но я думаю, что для вас было бы еще полезнее пройтись по вашему коду Python с помощью отладчика и посмотреть, что происходит, шаг за шагом.

SirGuy 19.09.2018 15:30

Я не думаю, что это источник ошибки, но я заметил, что вы делаете while x < width:..., но не устанавливаете x = 0 внутри цикла y

SirGuy 19.09.2018 15:31

Почему вы используете while вместо y в диапазоне (0, высота)?

Öö Tiib 19.09.2018 15:42

Я добавил всю ошибку (извините за это), и я добавил x = 0 внутри цикла y (как вы сказали: это был не источник)

chris 19.09.2018 15:51

Есть ли у вас конкретная причина не использовать какую-либо реализацию библиотеки? (Поиск в Google "преобразование радиальной симметрии Python" возвращает несколько вариантов).

GPhilo 19.09.2018 15:59

Я пробовал это (например, этот: github.com/ceilab/frst_python), но это не сработало, поскольку алгоритм кажется немного другим (я не получил реальных результатов, только почти черный вывод).

chris 19.09.2018 16:15

Разрывы строк в трассировке стека значительны. Теперь, когда он доступен для чтения, о чем вам говорят последние несколько строк? Какие размеры и действительные индексы у range?

Useless 19.09.2018 16:57

Алгоритм хотел увеличить позицию в массиве (изображении), которой нет. Это изображение 768x1024, поэтому от 0 до 1023. Но я не знаю, почему оно выходит за рамки.

chris 19.09.2018 17:17

Я бы использовал отладчик, чтобы увидеть значения tx, ty. Кроме того, разве result[ty, tx] не должен быть result[tx, ty]?

Ripi2 19.09.2018 20:39

tx было 1024, ty 0. Но это можно было исправить с помощью условия if. Должна быть другая ошибка.

chris 19.09.2018 20:49

Поскольку ошибка выхода за границы исправлена, есть ли у вас идеи, почему код не дает хорошего результата? @Бесполезный

chris 19.09.2018 23:39
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
11
511
1

Ответы 1

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

Другие вопросы по теме