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

2024-10-03 11:15:11 发布

您现在位置: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是梯度的低阈值和高阈值。在

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

enter image description hereenter image description here

这是我的python版本,但不幸的是我得到了一个错误:

^{pr2}$

代码:

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 hereenter image description here


Tags: imgnpzerosresultcv2rowsintgy