Ich habe ein Modul in C-Sprache erstellt, das von Python geladene Bilder filtert

Bei der Arbeit musste ich die Bildverarbeitung mit Python durchführen. Wenn es innerhalb des Bereichs liegt, der mit OpenCV usw. durchgeführt werden kann, ist das in Ordnung, aber der Filter des ursprünglichen Algorithmus hat keine praktische Geschwindigkeit, es sei denn, es ist C / C ++. Also habe ich ein Modul für Python in C-Sprache erstellt.

Wenn Sie es schnell ausprobieren möchten, verwenden Sie bitte mein Repository. https://github.com/soramimi/pymodule-image-filter

So erstellen Sie Ihr eigenes Modul für Python

Installation von abhängigen Modulen

Der erste Versuch ist "Hallo Welt", daher ist dies nicht erforderlich. Da in der späteren Bildverarbeitungsversion jedoch Numpy, Pillow und Matplotlib verwendet werden, müssen diese Module installiert werden. Es soll unter Ubuntu entwickelt werden. Benötigt ein Python-Entwicklungspaket.

sudo apt install python3-dev python3-matplotlib

Schreiben Sie eine Funktionsdefinitionsstruktur

.c


static PyMethodDef myMethods[] = {
	{ "helloworld", helloworld, METH_NOARGS, "My helloworld function." },
	{ NULL }
};

Der Inhalt der Definition wird in der Reihenfolge {(Funktionsname), (Zeiger auf Funktion), (Argumentübergabemethode), (Beschreibung)} beschrieben.

METH_NOARGS ist für Funktionen ohne Argumente. Verwenden Sie "METH_VARARGS", um das Argument zu verwenden.

Schreiben Sie eine Moduldefinitionsstruktur

.c


static struct PyModuleDef mymodule = {
	PyModuleDef_HEAD_INIT,
	"mymodule",
	"Python3 C API Module",
	-1,
	myMethods
};

Schreiben Sie den Modulnamen und die Beschreibung.

Schreiben Sie eine Funktion, die das Modul initialisiert

.c


PyMODINIT_FUNC PyInit_mymodule(void)
{
	import_array();
	return PyModule_Create(&mymodule);
}

Schreiben Sie den Funktionsaufruf import_array () nach Bedarf. Dies ist erforderlich, da sich dieses Thema mit Arrays in der Bildverarbeitung befasst. Wird nicht benötigt, wenn Sie keine Arrays verwenden. Sie müssen "import_array ()" für den gesamten Quellcode ausführen, der die Array-API verwendet.

Schreiben Sie den Funktionskörper

.c


static PyObject *helloworld(PyObject *self, PyObject *args)
{
	fprintf(stderr, "Hello, world\n");
	return Py_None;
}

Da es die erste Testfunktion ist, ist es "Hallo Welt". Später werden wir den Code implementieren, der die Bildverarbeitung durchführt.

Schreiben Sie ein Build-Skript

setup.py


from distutils.core import setup, Extension
setup(name = 'mymodule', version = '1.0.0', ext_modules = [Extension('mymodule', ['mymodule.c'])])

Bauen

python3 setup.py build_ext -i

Wenn Sie eine .so-Datei mit einem langen Namen haben, sind Sie erfolgreich.

$ ls *.so
mymodule.cpython-35m-x86_64-linux-gnu.so

Schreiben Sie ein Aufrufprogramm (Python-Seite)

main.py


import mymodule

mymodule.helloworld()

Lauf

Führen Sie die Python-Programm- und Moduldateien ".so" im selben Verzeichnis aus.

$ python3 main.py 
Hello, world

Erstellen Sie einen Bildverarbeitungsfilter

Verwenden wir als Beispiel eine Funktion, die einen Sepia-ähnlichen Filter anwendet. Der Funktionsname wurde von "Hallo Welt" in "Sepia" geändert.

Das Programm auf der Python-Seite ist wie folgt.

main.py


from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import mymodule

im = np.array(Image.open('kamo.jpg'))

im = mymodule.sepia(im)

print(type(im))
print(im.dtype)
print(im.shape)

plt.imshow(im)
plt.show()

Es funktioniert wie folgt.

  1. Laden Sie die Bilddatei
  2. Filter
  3. Sequenzinformationen anzeigen
  4. Zeigen Sie das Bild an

Die Funktionsdefinition lautet wie folgt.

.c


	{ "sepia", sepia, METH_VARARGS, "Sepia tone image filter" },

Dies ist ein Auszug aus der C-Sprachquelle.

mymodule.c


static PyObject *sepia(PyObject *self, PyObject *args)
{
	PyArrayObject *srcarray;
	if (!PyArg_ParseTuple(args, "O", &srcarray)) {
		fprintf(stderr, "invalid argument\n");
		return Py_None;
	}

Das erste (aber nur ein) Argument ist ein Array. Holen Sie es sich als Objekt.

Das Eingabearray ist ein dreidimensionales Array von (Höhe) x (Breite) x (Kanal), andernfalls tritt ein Fehler auf. Die Anzahl der Kanäle ist auf 3 (RGB) begrenzt.

.c


	if (srcarray->nd != 3) {
		fprintf(stderr, "invalid image\n");
		return Py_None;
	}
	if (srcarray->dimensions[2] != 3) {
		fprintf(stderr, "invalid image\n");
		return Py_None;
	}

Holen Sie sich die Größe des Bildes.

.c


	int h = srcarray->dimensions[0];
	int w = srcarray->dimensions[1];

Ordnen Sie ein Array zum Speichern des gefilterten Bildes zu.

.c


	npy_intp dims[] = { h, w, 3 };
	PyObject *image = PyArray_SimpleNew(3, dims, NPY_UBYTE);
	if (!image) {
		fprintf(stderr, "failed to allocate array\n");
		return Py_None;
	}

Verwechseln Sie nicht die Reihenfolge (Höhe) x (Breite) x (Kanal).

Als Array gesicherte Objekte können so umgewandelt werden, wie sie sind, um auf Zeiger auf die Array-Struktur zu verweisen.

.c


	PyArrayObject *dstarray = (PyArrayObject *)image;

Wenden Sie einen Filter an.

.c


	for (int y = 0; y < h; y++) {
		uint8_t const *src = (uint8_t const *)srcarray->data + y * w * 3;
		uint8_t *dst = (uint8_t *)dstarray->data + y * w * 3;
		for (int x = 0; x < w; x++) {
			uint8_t r = src[x * 3 + 0];
			uint8_t g = src[x * 3 + 1];
			uint8_t b = src[x * 3 + 2];
			r = pow(r / 255.0, 0.62) * 205 + 19;
			g = pow(g / 255.0, 1.00) * 182 + 17;
			b = pow(b / 255.0, 1.16) * 156 + 21;
			dst[x * 3 + 0] = r;
			dst[x * 3 + 1] = g;
			dst[x * 3 + 2] = b;
		}
	}

Geben Sie das Objekt zurück und beenden Sie den Vorgang.

.c


	return image;
}

das ist alles.

Fehlerbehandlung entfällt. Wenn die Funktion "None" ("Py_None") zurückgibt, z. B. wenn eine ungültige Bilddatei empfangen wird, sollte das praktische Programm den Fehler entsprechend behandeln.

Wie ich am Anfang schrieb, ist der vollständige Quellcode ** hier ) **.

image.png

Recommended Posts

Ich habe ein Modul in C-Sprache erstellt, das von Python geladene Bilder filtert
Versuchen Sie, ein Python-Modul in C-Sprache zu erstellen
Ich habe versucht, ein Python 3-Modul in C hinzuzufügen
Ich habe ein Python-Modul erstellt, um Kommentare zu übersetzen
Ich habe ein Paket erstellt, um Zeitreihen mit Python zu filtern
Ich habe ein Pay-Management-Programm in Python erstellt!
Ich habe eine Klasse erstellt, um das Analyseergebnis von MeCab in ndarray mit Python zu erhalten
Ich habe eine Webanwendung in Python erstellt, die Markdown in HTML konvertiert
Ich habe ein CLI-Tool erstellt, um Bilder in jedem Verzeichnis in PDF zu konvertieren
Ich habe ein Skript in Python erstellt, um MDD-Dateien in das Scrapbox-Format zu konvertieren
Ich habe ein Programm erstellt, um die Größe einer Datei mit Python zu überprüfen
Ich möchte mit Python ein Fenster erstellen
So fügen Sie Python ein Modul hinzu, das Sie in Julialang eingefügt haben
Ich habe ein Caesar-Kryptografieprogramm in Python erstellt.
Ich möchte eine Variable in einen Python-String einbetten
Ich möchte Timeout einfach in Python implementieren
Ich möchte in Python schreiben! (2) Schreiben wir einen Test
Ich habe ein Skript erstellt, um ein Snippet in README.md einzufügen
Ich habe versucht, einen Pseudo-Pachislot in Python zu implementieren
Ich möchte eine Datei mit Python zufällig testen
Ich möchte mit einem Roboter in Python arbeiten.
Ich habe eine Python-Bibliothek erstellt, die einen rollierenden Rang hat
Heap-Sortierung in C-Sprache
Fileinput, ein Modul, das das Schreiben von Perl-ähnlichen Filterprogrammen in Python erleichtert
Ich habe ein Programm erstellt, um Bilder mit Python und OpenCV in ASCII-Grafik umzuwandeln
Ich kann nicht schlafen, bis ich einen Server erstellt habe !! (Einführung in den Python-Server an einem Tag)
Ich habe einen Python-Text gemacht
Ich habe ein einfaches Tippspiel mit tkinter of Python gemacht
Ich habe versucht, einen eindimensionalen Zellautomaten in Python zu implementieren
Ich habe einen schnellen Feed-Reader mit Feedparser in Python erstellt
Ich habe einen Befehl zum Generieren eines Kommentars für eine Tabelle in Django eingegeben
Ich habe versucht "Wie man eine Methode in Python dekoriert"
Ich habe versucht, die Zeit und die Zeit der C-Sprache zu veranschaulichen
Ich habe mit Tkinter of Python ein Puzzlespiel (wie) gemacht
Ich habe eine Stoppuhr mit tkinter mit Python gemacht
Ich möchte eine schöne Ergänzung zu input () in Python hinzufügen
Verwenden Sie eine Skriptsprache für ein komfortables C ++ - Leben - OpenCV-Port Python zu C ++ -
Ich habe ein Skript in Python erstellt, um eine Textdatei für JSON zu konvertieren (für das vscode-Benutzer-Snippet).
Ich habe eine C ++ - Lernseite erstellt
Modultest mit mehreren Instanzen in C-Sprache
So fügen Sie MicroPython ein C-Modul hinzu ...
Ich habe einen Line-Bot mit Python gemacht!
So sammeln Sie Bilder in Python
ABC166 in Python A ~ C Problem
Ich habe mit Python eine Lotterie gemacht.
Einführung in Protobuf-c (C-Sprache ⇔ Python)
Löse ABC036 A ~ C mit Python
So verpacken Sie C in Python
Löse ABC037 A ~ C mit Python
Ich habe mit Python einen Daemon erstellt
Ich habe eine Bibliothek erstellt, die Konfigurationsdateien mit Python einfach lesen kann
Ich habe eine Funktion zum Laden des Git-Erweiterungsskripts in Python geschrieben
Ich habe versucht, ein missverstandenes Gefangenendilemma in Python zu implementieren
Ich habe ein Skript geschrieben, um Webseiten-Links in Python zu extrahieren
Übergeben Sie die Liste von Python an C ++ als Referenz in pybind11
Ich habe den Befehl gegeben, einen farbenfrohen Kalender im Terminal anzuzeigen
Ich habe einen verstümmelten Generator erstellt, der Ihre Lieblingssätze von UTF-8 bis Shift-JIS (cp932) in Python codiert