python - C++到Python的算法(径向对称变换)

标签 python c++ algorithm

我必须将径向对称变换算法从 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 是梯度的低阈值和高阈值。

该算法应将硬币图像向下变换为径向对称变换。

enter image description here enter image description here

这是我的 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)

对于我做错的任何建议,我将不胜感激。

编辑:我刚刚添加了一个不允许超出边界的条件,但是输出太高了,这意味着只有一个白色图像:

enter image description here

编辑 2:我将参数更改为 radSymTransform(gray, 1, 250, 255)(第一个)和 radSymTransform(gray, 10, 250, 255)(第二个)我得到的输出也不是很好:

enter image description here enter image description here

最佳答案

使用可以只使用库中内置的快速径向对称变换 link to the description

关于python - C++到Python的算法(径向对称变换),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52406902/

相关文章:

algorithm - 大 o 复杂度尺度函数 (n+1)^5/4n^2

c++ - 各种编译器上的 RDRAND 和 RDSEED 内在函数?

c++ - 简单的 GUI 应用程序在 Qt 5 中崩溃

algorithm - 如何跟踪 fifo 查询的最大值/最小值

python - 在另一个列表中添加一个列表

c++ - WM_KEYDOWN如何处理不同的按键?

vb.net - 有效地将列表划分为固定大小的 block

python - 为什么 python 找不到我的文件?

python - 使用 travis 和 heroku 进行持续部署——保留某种状态

python - 将 write.target 行压缩为一行?