/
githubmirror
/
nbs
Обзор
Документация
Войти
/
githubmirror
/
nbs
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
contrib/python/Pillow/py2/_imagingmorph.c
303 строки
8 KB
Anton Myagkov
Update ydb version to 24.4 (#4579)
07 фев 2026, 11:59
Не верифицирован
07 фев 2026, 11:59
2c21cae
Код
Авторство
О чём код?
/* * The Python Imaging Library * * A binary morphology add-on for the Python Imaging Library * * History: * 2014-06-04 Initial version. * * Copyright (c) 2014 Dov Grobgeld <dov.grobgeld@gmail.com> * * See the README file for information on usage and redistribution. */ #include "Python.h" #include "Imaging.h" #include "py3.h" #define LUT_SIZE (1<<9) /* Apply a morphologic LUT to a binary image. Outputs a a new binary image. Expected parameters: 1. a LUT - a 512 byte size lookup table. 2. an input Imaging image id. 3. an output Imaging image id Returns number of changed pixels. */ static PyObject* apply(PyObject *self, PyObject* args) { const char *lut; PyObject *py_lut; Py_ssize_t lut_len, i0, i1; Imaging imgin, imgout; int width, height; int row_idx, col_idx; UINT8 **inrows, **outrows; int num_changed_pixels = 0; if (!PyArg_ParseTuple(args, "Onn", &py_lut, &i0, &i1)) { PyErr_SetString(PyExc_RuntimeError, "Argument parsing problem"); return NULL; } if (!PyBytes_Check(py_lut)) { PyErr_SetString(PyExc_RuntimeError, "The morphology LUT is not a bytes object"); return NULL; } lut_len = PyBytes_Size(py_lut); if (lut_len < LUT_SIZE) { PyErr_SetString(PyExc_RuntimeError, "The morphology LUT has the wrong size"); return NULL; } lut = PyBytes_AsString(py_lut); imgin = (Imaging) i0; imgout = (Imaging) i1; width = imgin->xsize; height = imgin->ysize; if (imgin->type != IMAGING_TYPE_UINT8 || imgin->bands != 1) { PyErr_SetString(PyExc_RuntimeError, "Unsupported image type"); return NULL; } if (imgout->type != IMAGING_TYPE_UINT8 || imgout->bands != 1) { PyErr_SetString(PyExc_RuntimeError, "Unsupported image type"); return NULL; } inrows = imgin->image8; outrows = imgout->image8; for (row_idx=0; row_idx < height; row_idx++) { UINT8 *outrow = outrows[row_idx]; UINT8 *inrow = inrows[row_idx]; UINT8 *prow, *nrow; /* Previous and next row */ /* zero boundary conditions. TBD support other modes */ outrow[0] = outrow[width-1] = 0; if (row_idx==0 || row_idx == height-1) { for(col_idx=0; col_idx<width; col_idx++) outrow[col_idx] = 0; continue; } prow = inrows[row_idx-1]; nrow = inrows[row_idx+1]; for (col_idx=1; col_idx<width-1; col_idx++) { int cim = col_idx-1; int cip = col_idx+1; unsigned char b0 = prow[cim] &1; unsigned char b1 = prow[col_idx]&1; unsigned char b2 = prow[cip]&1; unsigned char b3 = inrow[cim]&1; unsigned char b4 = inrow[col_idx]&1; unsigned char b5 = inrow[cip]&1; unsigned char b6 = nrow[cim]&1; unsigned char b7 = nrow[col_idx]&1; unsigned char b8 = nrow[cip]&1; int lut_idx = (b0 |(b1 << 1) |(b2 << 2) |(b3 << 3) |(b4 << 4) |(b5 << 5) |(b6 << 6) |(b7 << 7) |(b8 << 8)); outrow[col_idx] = 255*(lut[lut_idx]&1); num_changed_pixels += ((b4&1)!=(outrow[col_idx]&1)); } } return Py_BuildValue("i",num_changed_pixels); } /* Match a morphologic LUT to a binary image and return a list of the coordinates of all matching pixels. Expected parameters: 1. a LUT - a 512 byte size lookup table. 2. an input Imaging image id. Returns list of matching pixels. */ static PyObject* match(PyObject *self, PyObject* args) { const char *lut; PyObject *py_lut; Py_ssize_t lut_len, i0; Imaging imgin; int width, height; int row_idx, col_idx; UINT8 **inrows; PyObject *ret = PyList_New(0); if (!PyArg_ParseTuple(args, "On", &py_lut, &i0)) { PyErr_SetString(PyExc_RuntimeError, "Argument parsing problem"); return NULL; } if (!PyBytes_Check(py_lut)) { PyErr_SetString(PyExc_RuntimeError, "The morphology LUT is not a bytes object"); return NULL; } lut_len = PyBytes_Size(py_lut); if (lut_len < LUT_SIZE) { PyErr_SetString(PyExc_RuntimeError, "The morphology LUT has the wrong size"); return NULL; } lut = PyBytes_AsString(py_lut); imgin = (Imaging) i0; if (imgin->type != IMAGING_TYPE_UINT8 || imgin->bands != 1) { PyErr_SetString(PyExc_RuntimeError, "Unsupported image type"); return NULL; } inrows = imgin->image8; width = imgin->xsize; height = imgin->ysize; for (row_idx=1; row_idx < height-1; row_idx++) { UINT8 *inrow = inrows[row_idx]; UINT8 *prow, *nrow; prow = inrows[row_idx-1]; nrow = inrows[row_idx+1]; for (col_idx=1; col_idx<width-1; col_idx++) { int cim = col_idx-1; int cip = col_idx+1; unsigned char b0 = prow[cim] &1; unsigned char b1 = prow[col_idx]&1; unsigned char b2 = prow[cip]&1; unsigned char b3 = inrow[cim]&1; unsigned char b4 = inrow[col_idx]&1; unsigned char b5 = inrow[cip]&1; unsigned char b6 = nrow[cim]&1; unsigned char b7 = nrow[col_idx]&1; unsigned char b8 = nrow[cip]&1; int lut_idx = (b0 |(b1 << 1) |(b2 << 2) |(b3 << 3) |(b4 << 4) |(b5 << 5) |(b6 << 6) |(b7 << 7) |(b8 << 8)); if (lut[lut_idx]) { PyObject *coordObj = Py_BuildValue("(nn)",col_idx,row_idx); PyList_Append(ret, coordObj); } } } return ret; } /* Return a list of the coordinates of all turned on pixels in an image. May be used to extract features after a sequence of MorphOps were applied. This is faster than match as only 1x1 lookup is made. */ static PyObject* get_on_pixels(PyObject *self, PyObject* args) { Py_ssize_t i0; Imaging img; UINT8 **rows; int row_idx, col_idx; int width, height; PyObject *ret = PyList_New(0); if (!PyArg_ParseTuple(args, "n", &i0)) { PyErr_SetString(PyExc_RuntimeError, "Argument parsing problem"); return NULL; } img = (Imaging) i0; rows = img->image8; width = img->xsize; height = img->ysize; for (row_idx=0; row_idx < height; row_idx++) { UINT8 *row = rows[row_idx]; for (col_idx=0; col_idx<width; col_idx++) { if (row[col_idx]) { PyObject *coordObj = Py_BuildValue("(nn)",col_idx,row_idx); PyList_Append(ret, coordObj); } } } return ret; } static int setup_module(PyObject* m) { PyObject* d = PyModule_GetDict(m); PyDict_SetItemString(d, "__version", PyUnicode_FromString("0.1")); return 0; } static PyMethodDef functions[] = { /* Functions */ {"apply", (PyCFunction)apply, METH_VARARGS, NULL}, {"get_on_pixels", (PyCFunction)get_on_pixels, METH_VARARGS, NULL}, {"match", (PyCFunction)match, METH_VARARGS, NULL}, {NULL, NULL, 0, NULL} }; #if PY_VERSION_HEX >= 0x03000000 PyMODINIT_FUNC PyInit__imagingmorph(void) { PyObject* m; static PyModuleDef module_def = { PyModuleDef_HEAD_INIT, "_imagingmorph", /* m_name */ "A module for doing image morphology", /* m_doc */ -1, /* m_size */ functions, /* m_methods */ }; m = PyModule_Create(&module_def); if (setup_module(m) < 0) return NULL; return m; } #else PyMODINIT_FUNC init_imagingmorph(void) { PyObject* m = Py_InitModule("_imagingmorph", functions); setup_module(m); } #endif