I want to use an external c function a numpy kernel operation on an image. For this the goal is to go through the image image only within the padding so that the kernel does not go outside the image. In the following debugging code, I first generate a matrix filled with 1
in the python script. I then pass this matrix with its dimension to the c function. I iterate over rows and column and want to set the value to 9
if I am on the border of the matrix (in the padding) and to 8
if I am within the part of the matrix where I want to do the computation.
The eventual goal of the computation is to do a computation for every entry of the matrix taking all the neighbours (e.g. on a 3x3 matrix pattern) for that computation. For a 3x3 matrix, the search has to start before the stop after the first row/column and stop before the last row column.
The result I want to have is the following:
,0,1,2,3
0,9,9,9,9
1,9,8,8,9
2,9,8,8,9
3,9,9,9,9
Instead I get the following:
,0,1,2,3
0,9,9,9,9
1,8,8,8,8
2,8,8,8,8
3,8,1,1,1
Here is the .sh
script debug_scriptsh.sh
:
a=debug_scriptc && cc -fPIC -shared -o $a.so $a.c && python debug_scriptpy.py && open debug_table.csv
the .py
script debug_scriptc.c
:
import ctypes
import pandas as pd
import numpy as np
import sys
import pdb
DLL_NAME = "./debug_scriptc.{:s}".format("dll" if sys.platform[:3].lower() == "win" else "so")
def np_mat_type(rows, cols, element_type=float):
return np.ctypeslib.ndpointer(dtype=element_type, shape=(rows, cols), flags="C_CONTIGUOUS")
rows0 = 4
cols0 = 4
kernel_size = 3
dll = ctypes.CDLL(DLL_NAME)
matrix_func = dll.matrixFunc4matin
matrix_func.argtypes = (
ctypes.c_size_t,
np_mat_type(rows0, cols0),
ctypes.c_size_t,
ctypes.c_size_t
)
matrix_func.restype = np_mat_type(rows0, cols0)
dealloc_array = dll.deallocArray
dealloc_array.argtypes = (np_mat_type(rows0, cols0),)
dealloc_array.restype = None
u_rms_array = np.zeros((rows0, cols0))
velocity_image_ones = np.empty((rows0, cols0))
velocity_image_ones[:] = 1
u_rms_array = matrix_func(
kernel_size,
velocity_image_ones,
rows0,
cols0
)
debug_DF_u_rms_array_C = pd.DataFrame(u_rms_array.astype(int))
debug_DF_u_rms_array_C.to_csv("debug_table.csv")
dealloc_array(u_rms_array)
the .c
script debug_scriptc.c
:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#if defined(_WIN32)
# define DLL00_EXPORT_API __declspec(dllexport)
#else
# define DLL00_EXPORT_API
#endif
#define ELEMENT_TYPE double
#if defined(__cplusplus)
extern "C" {
#endif
DLL00_EXPORT_API ELEMENT_TYPE* matrixFunc4matin(
size_t kernel_size,
const ELEMENT_TYPE *pvelocity_image_ones,
size_t rows0,
size_t cols0
);
DLL00_EXPORT_API void deallocArray(ELEMENT_TYPE *pMat);
#if defined(__cplusplus)
}
#endif
ELEMENT_TYPE* matrixFunc4matin(
size_t kernel_size,
const ELEMENT_TYPE *pvelocity_image_ones,
size_t rows0,
size_t cols0
)
{
size_t matSize = sizeof(ELEMENT_TYPE) * cols0 * rows0;
ELEMENT_TYPE *pRet = (ELEMENT_TYPE*)(malloc(matSize));
memcpy(pRet, pvelocity_image_ones, matSize);
int start_kern_search = kernel_size - 2;
int end_kern_search_rows = rows0 - (kernel_size-1)/2;
int end_kern_search_cols = cols0 - (kernel_size-1)/2;
for (int i_velmap = 0; i_velmap < rows0; i_velmap++){
for (int j_velmap = 0; j_velmap < cols0; j_velmap++){
if (i_velmap < start_kern_search | i_velmap > end_kern_search_rows | j_velmap < start_kern_search | j_velmap > end_kern_search_cols){
pRet[i_velmap * cols0 + j_velmap] = 9;
continue;
}
else
{
pRet[i_velmap * end_kern_search_cols + j_velmap] = 8;
}
}
}
return pRet;
}
void deallocArray(ELEMENT_TYPE *pMat)
{
if (pMat)
free(pMat);
}