Algoritmo de C ++ para Python (simetria radial transformar)

votos
0

Eu tenho que transformar a simetria radial algoritmo de transformação de C ++ para Python. Eu sou muito novo para python e nunca ter usado 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)++;
            }
        }
    }
}

Leva a x e y gradientes e o raio de detecção (raios). minval e maxval são baixas e altas limiares para o gradiente.

O algoritmo deve transformar a imagem da moeda abaixo para transformar a simetria radial.

digite digite

Esta é minha versão python, mas infelizmente eu recebo um erro:

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)

Ficaria muito grato por qualquer conselho que eu fiz de errado.

Edit: Acabei de adicionar uma condição que não é permitido a correr para fora das fronteiras, mas a saída é alta, isso significa apenas uma imagem branca:

digite

Edit 2: Eu mudei os parâmetros a radSymTransform(gray, 1, 250, 255)(primeira) e radSymTransform(gray, 10, 250, 255)(segundo) e eu tenho essa saída que também não é muito bom:

digite digite

Publicado 19/09/2018 em 13:22
fonte usuário
Em outras línguas...                            

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