0

我正在编写一个用于 python 的 c 函数。运行时会发生分段错误,根据 printf 调用,会在 if 子句中抛出该错误。shell 的输出是:

row 1, col 0: 1.000000
row:0, -col:0, index:0
-2: 0.000000
else
row:0, -col:1, index:1
-2: 0.000000
else
row:0, -col:2, index:2
-2: 0.000000
else
row:0, -col:3, index:3
-2: 0.000000
else
row:0, -col:4, index:4
-2: 0.000000
else
row:1, -col:0, index:5
-2: 1.000000
Speicherzugriffsfehler (Speicherabzug geschrieben)

(最后一行表示分段错误)

c代码是:

#include <stdio.h>
#include <math.h>

#define pi 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679

void hough(const void* img, int imgRowCount, int imgColCount, const void* thetas, int thetaCount, const void* rhos, int rhoCount, void* out)
{

  const double* imgD = (double*) img;
  double* outD = (double*)out;

  const double* thetasD = (double*)thetas;
  const double* rhosD = (double*)rhos;



  printf("row 1, col 0: %f\n", imgD[getIndex(1, 0, imgColCount)]);


  int row, col, thetaInd, rhoInd, index;
  double rhoVal, minDiff, diff, tmp;
  for(row = 0; row<imgRowCount; row++)
  {
      for(col = 0; col<imgColCount; col++)
      {
          printf("row:%d, -col:%d, index:%d\n", row, col, getIndex(row, col, imgColCount));
          tmp = imgD[getIndex(row, col, imgColCount)];
          printf("-2: %f\n", tmp);
          if (tmp>0.0)
          {
              printf("-1");
              for(thetaInd = 0; thetaInd<thetaCount; thetaInd++)
              {
                  rhoVal = col*cos(thetasD[thetaInd]*(pi/180)) + row*sin(thetasD[thetaInd]*(pi/180));
                  minDiff = INFINITY;
                  index = -1;
                  for(rhoInd = 0; rhoInd<rhoCount; rhoInd++)
                  {
                      diff = abs(rhoVal-rhosD[rhoInd]);
                      if(diff<minDiff)
                      {
                          minDiff = diff;
                          index = rhoInd;
                      }
                  }
                  if(index>=0)
                  {
                    printf("1\n");
                    outD[getIndex(index, thetaInd, thetaCount)] += 1;
                  }
              }
          }
          else
          {
            printf("else\n");
          }
      }

  }


}



int getIndex(int row, int col, int maxCol)
{
    return col + row*maxCol;
}

最后使用了python代码:

import numpy as np
import ctypes
from scipy.misc import imread



def makeReady(arr):
  return np.require(arr, dtype=np.double, requirements=["C_CONTIGUOUS"])



def hough(imgBin, thetaRes=1, rhoRes=1):
  if len(imgBin.shape) > 2:
    imgBin = np.mean(imgBin, axis=2)

  if imgBin.max() > 1:
    imgBin /= imgBin.max()

  if ((imgBin!=0) * (imgBin!=1)).sum()>0:
    imgBin = imgBin > (imgBin.max()/2.0)

  nR,nC = imgBin.shape
  theta = np.linspace(-90.0, 90.0, np.ceil(180.0/thetaRes) + 1.0)
  D = np.sqrt((nR - 1)**2 + (nC - 1)**2)
  q = np.ceil(D/rhoRes)
  nrho = 2*q + 1
  rho = np.linspace(-q*rhoRes, q*rhoRes, nrho)
  H = np.zeros((len(rho), len(theta)))


  imgC = makeReady(imgBin)
  thetasC = makeReady(theta)
  rhosC = makeReady(rho)
  outC = makeReady(H)


  lib = ctypes.cdll.LoadLibrary("./hough.so")
  lib.hough(imgC.ctypes.data_as(ctypes.c_void_p), imgC.shape[0], imgC.shape[1], thetasC.ctypes.data_as(ctypes.c_void_p), len(thetasC), rhosC.ctypes.data_as(ctypes.c_void_p),outC.ctypes.data_as(ctypes.c_void_p))



if __name__ == "__main__":
  img = 1 - (imread("lines.jpeg"))>125
  print img.shape
  a = np.zeros((5,5))
  a[1,0] = 5
  hough(a)

我究竟做错了什么?谢谢

4

2 回答 2

0

唯一看起来可能导致该错误的是数组越界。使用getIndex(...)里面的函数[]可能会导致你的问题。

但是,由于难以阅读代码(没有注释,也没有上下文),我建议使用调试器(如valgrind)为您提供有关错误位置的信息。事实上,如果您使用调试符号(在 gcc 和 clang 上)valgrind编译,甚至会打印发生错误的行号。-g -O0

于 2013-10-03T13:59:29.640 回答
0

从输出来看,这部分代码似乎发生了错误:

          for(thetaInd = 0; thetaInd<thetaCount; thetaInd++)
          {
              rhoVal = col*cos(thetasD[thetaInd]*(pi/180)) + row*sin(thetasD[thetaInd]*(pi/180));
              minDiff = INFINITY;
              index = -1;
              for(rhoInd = 0; rhoInd<rhoCount; rhoInd++)
              {
                  diff = abs(rhoVal-rhosD[rhoInd]);
                  if(diff<minDiff)
                  {
                      minDiff = diff;
                      index = rhoInd;
                  }
              }

              if(index>=0)
              {
                printf("1\n");
                outD[getIndex(index, thetaInd, thetaCount)] += 1;
              }
          }

thetasD只有通过访问三个数组之一( andrhosDoutD)超出其范围,才会在此处导致分段违规。

这只有在索引运行到很远的情况下才会发生,而这反过来也只会在 for 循环的中断条件错误的情况下发生,只有当错误的值被传递给时才会发生hough

后者似乎确实如此,因为 Python 脚本缺少传递rho的大小,但没有传递任何outD.

这一行:

lib.hough(imgC.ctypes.data_as(ctypes.c_void_p), imgC.shape[0], imgC.shape[1], 
  thetasC.ctypes.data_as(ctypes.c_void_p), len(thetasC), 
  rhosC.ctypes.data_as(ctypes.c_void_p), 
  outC.ctypes.data_as(ctypes.c_void_p))

应该看起来像:

 lib.hough(imgC.ctypes.data_as(ctypes.c_void_p), imgC.shape[0], imgC.shape[1],
   thetasC.ctypes.data_as(ctypes.c_void_p), len(thetasC), 
   rhosC.ctypes.data_as(ctypes.c_void_p), len(rhosC), 
   outC.ctypes.data_as(ctypes.c_void_p))
于 2013-10-03T14:08:56.273 回答