我必须将径向对称变换算法从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是该梯度的高低阈值。
该算法应将硬币图像向下变换为径向对称变换。
这是我的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)
对于任何建议,我做错了我将不胜感激。
编辑:我刚刚添加了一个条件,即不允许其超出边界,但是输出过高,这意味着只有白色图像:
编辑2:我将参数更改为radSymTransform(gray, 1, 250, 255)
(第一)和radSymTransform(gray, 10, 250, 255)
(第二),但得到的输出也不是很好: