我想使用外部 c 函式對影像進行 numpy 內核操作。為此,目標是僅在填充內遍歷影像影像,以便內核不會超出影像。1在下面的除錯代碼中,我首先生成了一個在 python 腳本中填充的矩陣。然后我將這個矩陣及其維度傳遞給 c 函式。我遍歷行和列,并希望將值設定為9是否在矩陣的邊界(在填充中)以及8是否在我想要進行計算的矩陣部分內。
計算的最終目標是對矩陣的每個條目進行計算,并為該計算獲取所有鄰居(例如,在 3x3 矩陣模式上)。對于 3x3 矩陣,搜索必須在第一行/列之后的停止之前開始,并在最后一行列之前停止。
我想要的結果如下:
,0,1,2,3
0,9,9,9,9
1,9,8,8,9
2,9,8,8,9
3,9,9,9,9
相反,我得到以下資訊:
,0,1,2,3
0,9,9,9,9
1,8,8,8,8
2,8,8,8,8
3,8,1,1,1
這是.sh腳本debug_scriptsh.sh:
a=debug_scriptc && cc -fPIC -shared -o $a.so $a.c && python debug_scriptpy.py && open debug_table.csv
.py腳本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)
.c腳本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);
}
uj5u.com熱心網友回復:
[SO]的繼續:如何在 C 中撰寫一個函式,該函式將兩個矩陣作為輸入作為 numpy array。
問題是指數計算。
當將(小)矩形(內部)構圖(居中)成較大的矩形(外部)時,邊緣公式(在每個軸(維度)上)為:
edge = (outer_dim - inner_dim) / 2
dll00.c:
#include <math.h>
#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* matrixFormat(const ELEMENT_TYPE *pMat, size_t rows, size_t cols, size_t kernel);
DLL00_EXPORT_API void deallocArray(ELEMENT_TYPE *pMat);
#if defined(__cplusplus)
}
#endif
#define MIN_EDGE 1
#define PAD_VAL 9
#define KERNEL_VAL 8
static size_t edge(size_t dim, size_t kernel, size_t minEdge)
{
if (kernel >= dim)
return minEdge;
size_t ret = (dim - kernel) / 2;
return (ret > minEdge) ? ret : minEdge;
}
ELEMENT_TYPE* matrixFormat(
const ELEMENT_TYPE *pMat,
size_t rows,
size_t cols,
size_t kernel)
{
size_t matSize = sizeof(ELEMENT_TYPE) * cols * rows;
ELEMENT_TYPE *pRet = (ELEMENT_TYPE*)(malloc(matSize));
printf("\nC: - matrix (%zu X %zu (%zu)):\n", rows, cols, kernel);
size_t minRow = edge(rows, kernel, MIN_EDGE),
minCol = edge(cols, kernel, MIN_EDGE);
size_t maxRow = rows - minRow - 1,
maxCol = cols - minCol - 1;
for (size_t i = 0; i < rows; i) {
for (size_t j = 0; j < cols; j) {
pRet[i * cols j] = ((i >= minRow) && (i <= maxRow) && (j >= minCol) && (j <= maxCol)) ? KERNEL_VAL : PAD_VAL;
}
}
return pRet;
}
void deallocArray(ELEMENT_TYPE *pMat)
{
if (pMat)
free(pMat);
}
代碼00.py:
#!/usr/bin/env python
import ctypes as cts
import sys
import numpy as np
DLL_NAME = "./dll00.{:s}".format("dll" if sys.platform[:3].lower() == "win" else "so")
ELEMENT_TYPE = cts.c_double
def np_mat_type(rows, cols, element_type=ELEMENT_TYPE):
return np.ctypeslib.ndpointer(dtype=element_type, shape=(rows, cols), flags="C_CONTIGUOUS")
def main(*argv):
np.set_printoptions(precision=3)
dll = cts.CDLL(DLL_NAME)
matrix_format = dll.matrixFormat
dealloc_array = dll.deallocArray
dealloc_array.restype = None
values = (
(4, 4, 3),
(6, 6, 3),
#(3, 3, 3),
)
for rows, cols, kernel in values:
print("\nRows: {:d}, Cols: {:d}, Kernel: {:d}".format(rows, cols, kernel))
mat = np.ones((rows, cols), dtype=ELEMENT_TYPE)
matrix_format.argtypes = (np_mat_type(rows, cols), cts.c_size_t, cts.c_size_t, cts.c_size_t)
matrix_format.restype = np_mat_type(rows, cols)
dealloc_array.argtypes = (np_mat_type(rows, cols),)
print("mat:")
print(mat)
mat_res = matrix_format(mat, rows, cols, kernel)
print("result:")
print(mat_res)
dealloc_array(mat_res)
if __name__ == "__main__":
print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
64 if sys.maxsize > 0x100000000 else 32, sys.platform))
rc = main(*sys.argv[1:])
print("\nDone.\n")
sys.exit(rc)
輸出:
(qaic-env) [cfati@cfati-5510-0:/mnt/e/Work/Dev/StackOverflow/q074171783]> ~/sopr.sh ### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ### [064bit prompt]> ls code00.py dll00.c [064bit prompt]> gcc -fPIC -shared -o dll00.so dll00.c [064bit prompt]> ls code00.py dll00.c dll00.so [064bit prompt]> python ./code00.py Python 3.8.10 (default, Jun 22 2022, 20:18:18) [GCC 9.4.0] 064bit on linux Rows: 4, Cols: 4, Kernel: 3 mat: [[1. 1. 1. 1.] [1. 1. 1. 1.] [1. 1. 1. 1.] [1. 1. 1. 1.]] C: - matrix (4 X 4 (3)): result: [[9. 9. 9. 9.] [9. 8. 8. 9.] [9. 8. 8. 9.] [9. 9. 9. 9.]] Rows: 6, Cols: 6, Kernel: 3 mat: [[1. 1. 1. 1. 1. 1.] [1. 1. 1. 1. 1. 1.] [1. 1. 1. 1. 1. 1.] [1. 1. 1. 1. 1. 1.] [1. 1. 1. 1. 1. 1.] [1. 1. 1. 1. 1. 1.]] C: - matrix (6 X 6 (3)): result: [[9. 9. 9. 9. 9. 9.] [9. 8. 8. 8. 8. 9.] [9. 8. 8. 8. 8. 9.] [9. 8. 8. 8. 8. 9.] [9. 8. 8. 8. 8. 9.] [9. 9. 9. 9. 9. 9.]] Done.
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/519660.html
