Lesen Sie zuerst verschiedene Dinge und erhalten Sie dann 200 * 200 maharo.jpg. Dies ist Kawauso [Mahalo-Kun] im Sunshine Aquarium (https://wikiwiki.jp/kawausotter/%E3%83%9E%E3%83%8F%E3%83%AD%EF%BC%88%E3% 82% B5% E3% 83% B3% E3% 82% B7% E3% 83% A3% E3% 82% A4% E3% 83% B3% E6% B0% B4% E6% 97% 8F% E9% A4% Es ist ein Bild von A8% EF% BC% 89).
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
src = cv.imread("maharo.jpg ", cv.IMREAD_GRAYSCALE)
h, w = src.shape[::-1] # w=200, h=200
plt.subplot(111),plt.imshow(src,cmap = 'gray')
plt.title('otter image'), plt.xticks([]), plt.yticks([])
plt.show()
Als nächstes legen Sie die Variablen um die GPU herum fest.
Sie können überprüfen, ob die GPU aktiviert ist, indem Sie überprüfen, ob "cv2.cuda.getCudaEnabledDeviceCount ()" eine Zahl größer oder gleich 1 zurückgibt.
Grundsätzlich kann CUDA-fähiges OpenCV verwendet werden, indem "cv2.function" in "cv2.cuda.function" umgeschrieben wird. (Es gibt einige Ausnahmen, wie z. B. die Übereinstimmung dieser Vorlage. Weitere Informationen finden Sie unter dir (cv2.cuda)
.)
Zusätzlich wird der Speicher von Variablen und GPU durch "cv2.cuda_GpuMat ()" gesichert, und Informationen werden zwischen den Speichern durch ".upload () /. Download ()" ausgetauscht.
print(cv.cuda.getCudaEnabledDeviceCount())
g_src = cv.cuda_GpuMat()
g_dst = cv.cuda_GpuMat()
g_src.upload(src)
Vorerst habe ich das Bild von Mahalo auf die GPU verschoben. Resize Lassen Sie uns den Geschmack des GPU-Materials mit nur Resize (512-> 2K) erleben, das keine Lese- / Schreibinformationen in der Schleife enthält. CUDA unterstützt übrigens keine Lanczos-Interpolation. (Es gibt so etwas im Großen und Ganzen) CPU
%%timeit
cpu_dst = cv.resize(src, (h*10, w*10), interpolation=cv.INTER_CUBIC)
# 777 µs ± 8.06 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
CUDA
%%timeit
g_dst = cv.cuda.resize(g_src, (h*4, w*4), interpolation=cv.INTER_CUBIC)
# 611 µs ± 6.34 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
__ Der Geschmack des Materials ist langsam __ Dies hat zu einigen Nicht-GPU-Vorteilen geführt. Übrigens ist die Ausführungsgeschwindigkeit beim Lesen und Schreiben von der CPU langsamer.
%%timeit
g_src.upload(src)
g_dst = cv.cuda.resize(g_src, (h*4, w*4), interpolation=cv.INTER_CUBIC)
gpu_dst = g_dst.download()
# 1.51 ms ± 16.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Obwohl es mir schwer gefallen ist, CUDA einzusetzen, gefällt es mir nicht. Nun, parallel dazu sieht es nicht so aus, ist es schwierig? Es scheint, dass das Lesen und Schreiben ungefähr 800 μs dauert. Wovon hängt das ab? Ich denke, dass PCIe 3.0 der Engpass sein wird (keine Basis)
Template Matching Lassen Sie uns einen zweiten Blick darauf werfen und einen Vorlagenabgleich durchführen, der parallel nützlich zu sein scheint.
ex_src = cv.resize(src, (h*10, w*10), interpolation=cv.INTER_CUBIC)
tmpl = ex_src[1000:1200, 1000:1200]
th, tw = tmpl.shape[::-1]
CPU
%%timeit
result = cv.matchTemplate(ex_src, tmpl, cv.TM_CCOEFF_NORMED)
# 138 ms ± 5.03 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Es ist nicht langsamer als ich erwartet hatte ... (Ergänzung: Wahrscheinlich, weil der Prozess auf 32 Threads ausgeführt wird.)
result = cv.matchTemplate(ex_src, tmpl, cv.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result)
top_left = max_loc
bottom_right = (top_left[0] + th, top_left[1] + tw)
cv.rectangle(ex_src,top_left, bottom_right, 255, 2)
plt.subplot(121),plt.imshow(result,cmap = 'gray')
plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(ex_src,cmap = 'gray')
plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
plt.show()
CUDA Die CUDA-Version der Vorlagenbearbeitung ist etwas speziell (für Python), wird jedoch als "createTemplateMatching (Genauigkeit, METHODE)" definiert.
gsrc = cv.cuda_GpuMat()
gtmpl = cv.cuda_GpuMat()
gresult = cv.cuda_GpuMat()
gsrc.upload(ex_src)
gtmpl.upload(tmpl)
matcher = cv.cuda.createTemplateMatching(cv.CV_8UC1, cv.TM_CCOEFF_NORMED)
%%timeit
gresult = matcher.match(gsrc, gtmpl)
# 10.5 ms ± 406 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
__ Das Material schmeckt gut __ CPU: Im Vergleich zu 138 ms hat CUDA eine Geschwindigkeit von 10,5 ms erreicht, was etwa zehnmal schneller ist.
%%timeit
gsrc.upload(ex_src)
gtmpl.upload(tmpl)
matcher = cv.cuda.createTemplateMatching(cv.CV_8UC1, cv.TM_CCOEFF_NORMED)
gresult = matcher.match(gsrc, gtmpl)
resultg = gresult.download()
# 16.6 ms ± 197 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Selbst wenn Sie das Lesen / Schreiben berechnen, ist es immer noch ungefähr achtmal schneller. Dies ist bei der GTX 1080 der Fall, also mit der kürzlich erwähnten GPU der Ampere-Generation noch schneller ...? Ich brauche nur max_locg, aber gibt es eine Möglichkeit, max_locg im Gresult-Stadium abzurufen?
gresult = matcher.match(gsrc, gtmpl)
resultg = gresult.download()
min_valg, max_valg, min_locg, max_locg = cv.minMaxLoc(resultg)
top_leftg = max_locg
bottom_rightg = (top_leftg[0] + tw, top_leftg[1] + th)
cv.rectangle(src,top_leftg, bottom_rightg, 255, 2)
plt.subplot(121),plt.imshow(resultg,cmap = 'gray')
plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(ex_src,cmap = 'gray')
plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
plt.show()
print(max_loc,max_locg)
# (1000, 1000) (1000, 1000)
Das gleiche Ergebnis wird erhalten.
Der diesmal verwendete Code (Jupyter Notebook) wird auf Github veröffentlicht.
Testcode Erstellen Sie OpenCV mit aktiviertem CUDA unter Ubuntu
Recommended Posts