C# Resize Image mit OpenCL

roker002

Commander
Registriert
Dez. 2007
Beiträge
2.103
Ich habe mal im Internet herumgesucht aber nicht gefunden, wie man von einem Bild die Größe ändern kann. Ich spreche hier von Resizing/Croping mit OpenCL.


Hat jemand vielleicht einen Tutorial Link wo ich mir genau anschauen kann? Ich dachte, ich könnte ja auch außerhalb des normalen Programmierbereich auch was lernen. OpenCL bietet vieles mit Vektorenberechnungen, was ich vorerst nicht brauche und noch nicht benutzen möchte.


Eine andere Frage. Also mit OpenCL kann man keine zusätzliche Threads erzeugen oder? Habe nachgeforscht und bin auf eine Unsichere Quelle gestoßen, wo es gesagt wird, dass es sowas nicht geht! Naja, wenn man schon auf der GraKa arbeitet, wieso sollte die Karte auch keine Multithreads anbieten. Aber ich kann schon nachvollziehen das die Kerntechnologie der GraKa in der Mathematik liegt und nicht in der Nebenläufigkeit :D
 
OpenCL stellt dir nur die möglichkeit einen kernel mit einer festen "Threadzahl" laufen zu lassen.
kann auch sein das du arrays nehmen musst, weiß net wie weit image implementiert ist... als ich das gelernt hab, gabs noch keine images...
wenn du images verwendest kommst du mit z.b. FuReadImagef an die pixel.
und mit FuWriteImagef kannst du sie wieder schreiben

bilder corpen ist relativ einfach

du musst den kernel mit der worksize der ausgewählten größe starten. und dann einfach die position draufaddieren (nur beim alten bild) um die daten aus dem alten in das neue bild zu laden...

resize ist schwieriger, damit das sauber wird brauchst du beim verkleinern einen gausfilter, und beim vergrößern musst du bikubisch interpolieren. sonst bekommst du artefakte

verkleinern kannst du mit einer faltung von binominalkoeffizenten (erst zeilen dann spalten) machen und dann jeden zweiten pixel auswählen.
geigenet zu faltung ist: 1/16 * (1 4 6 4 1) bzw. 1/16 * (1 4 6 4 1).
schau hier: http://de.wikipedia.org/wiki/Faltung_(Mathematik)

vergrößern musst du zwischen den pixeln interpolieren, entweder linear oder bikubisch.

das in opencl zu bringen ist eigentlich relativ einfach, du kannst pixel (croping) bzw. zeilen und spalten (verkleinern / vergrößern) parallel behandeln. wenn es in c oder java implementiert hast, hast du 90% er arbeit erledigt.

also so etwa fürs verkleinern(keine gewähr, es ist spät und ich habs net getestet)
die bildgröße sollte auf dem host device festgelegt werden

int x = get_global_id(0); //id zeilen
int y = get_global_id(1); //id spalten
int2 size = {get_global_size(0), get_global_size(1)}; //anzahl zeilen, spalten
__global float gaus[5] = {1 /16, 4/16, 6/16, 4/16, 1/16}
int i,j;
for(i = -4; i < size.s1; ++i) // über zeilen
{
for(j=0; j < 5; ++j)
{
if(i+j < 0 || i+j >=size.s0) continue;
int2 cord = {x, i+j}
float4 pixel = FuReadImagef(img, cord, size)
pixel *= gaus[j];
FuWriteImagef(img, cord, size, pixel);
}
}

for(i = -4; i < size.s0; ++i) // über spalten
{
for(j=0; j < 5; ++j)
{
if(i+j < 0 || i+j >=size.s1) continue;
int2 cord = {i+j,y}
float4 pixel = FuReadImagef(img, cord, size)
pixel *= gaus[j];
FuWriteImagef(img, cord, size, pixel);
}
}

das wäre ein gausfilter, jetzt einfach jedes zweite pixel auswählen....
 
Zuletzt bearbeitet:
Danke erstmal....

ooh man wie ich LinAlgebra hasse :D

Werde mir alles durchlesen... man habe seit 3 Jahren schon LinAlg nicht gemacht.

Melde mich nochmal wenn sich was ergibt, oder fragen gibt :P
 
Zurück
Oben