Algoritmo de C ++ para Python (transformada de simetría radial)

votos
0

Tengo que transformar la simetría radial algoritmo de la transformada de C ++ para Python. Estoy muy nuevo en Python y nunca he utilizado 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)++;
            }
        }
    }
}

Toma la x y gradientes de Y y el radio de detección (rayos). MINVAL y maxval son umbrales alto y bajo para el gradiente.

El algoritmo debe transformar la imagen de la moneda abajo a la simetría radial transformar.

introducir introducir

Esta es mi versión de Python, pero por desgracia me sale un error:

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

código:

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)

Le agradecería cualquier consejo lo que hice mal.

Edit: Acabo de añadir una condición que no se permite que se quede sin fronteras, pero la salida es alta, esto significa simplemente una imagen en blanco:

introducir

Edición 2: He cambiado los parámetros a radSymTransform(gray, 1, 250, 255)(primero) y radSymTransform(gray, 10, 250, 255)(segundo) y me dieron esta salida que tampoco es muy buena:

introducir introducir

Publicado el 19/09/2018 a las 13:22
fuente por usuario
En otros idiomas...                            

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more