org.bytedeco.javacv.JavaCVCL Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of javacv Show documentation
Show all versions of javacv Show documentation
Java interface to OpenCV, FFmpeg, and more
/*
* Copyright (C) 2011-2012 Samuel Audet
*
* Licensed either under the Apache License, Version 2.0, or (at your option)
* under the terms of the GNU General Public License as published by
* the Free Software Foundation (subject to the "Classpath" exception),
* either version 2, or any later version (collectively, the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.gnu.org/licenses/
* http://www.gnu.org/software/classpath/license.html
*
* or as provided in the LICENSE.txt file that accompanied this code.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.bytedeco.javacv;
import com.jogamp.opencl.CLCommandQueue;
import com.jogamp.opencl.CLBuffer;
import com.jogamp.opencl.CLContext;
import com.jogamp.opencl.CLDevice;
import com.jogamp.opencl.CLEventList;
import com.jogamp.opencl.CLImage2d;
import com.jogamp.opencl.CLImageFormat;
import com.jogamp.opencl.CLImageFormat.ChannelOrder;
import com.jogamp.opencl.CLImageFormat.ChannelType;
import com.jogamp.opencl.CLKernel;
import com.jogamp.opencl.CLMemory;
import com.jogamp.opencl.CLObject;
import com.jogamp.opencl.CLPlatform;
import com.jogamp.opencl.CLProgram;
import com.jogamp.opencl.CLProgram.CompilerOptions;
import com.jogamp.opencl.gl.CLGLContext;
import com.jogamp.opencl.gl.CLGLImage2d;
import com.jogamp.opencl.gl.CLGLObject;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLCapabilitiesImmutable;
import com.jogamp.opengl.GLContext;
import com.jogamp.opengl.GLDrawableFactory;
import com.jogamp.opengl.GLException;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.glu.GLU;
import java.io.InputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.nio.ByteBuffer;
import java.util.Vector;
import java.util.logging.Logger;
import org.bytedeco.javacpp.Loader;
import org.bytedeco.javacpp.BytePointer;
import org.bytedeco.opencv.opencv_core.*;
import org.bytedeco.opencv.opencv_imgproc.*;
import static org.bytedeco.opencv.global.opencv_core.*;
import static org.bytedeco.opencv.global.opencv_imgcodecs.*;
import static org.bytedeco.opencv.global.opencv_imgproc.*;
/**
*
* @author Samuel Audet
*
* To make NVIDIA drivers happy, we may need to limit the maximum
* heap memory size of Java to 1 GB, by defining something like
* export _JAVA_OPTIONS=-Xmx1G
*
*/
public class JavaCVCL {
public JavaCVCL(CLContext context) {
this(context, context.getDevices()[0]);
}
public JavaCVCL(CLContext context, CLDevice device) {
// this.pbuffer = null;
this.context = context;
this.glu = context instanceof CLGLContext ? new GLU() : null;
this.commandQueue = device.createCommandQueue(/*Mode.PROFILING_MODE*/);
CLKernel[] kernels = buildKernels(fastCompilerOptions, "JavaCV.cl", "pyrDown", "remap", "remapBayer");
this.pyrDownKernel = kernels[0];
this.remapKernel = kernels[1];
this.remapBayerKernel = kernels[2];
}
public static GLCapabilities getDefaultGLCapabilities(GLProfile profile) {
GLCapabilities caps = new GLCapabilities(profile != null ? profile : GLProfile.getDefault());
// Without line below, there is an error on Windows.
caps.setDoubleBuffered(false);
return caps;
}
public JavaCVCL() {
this(false);
}
public JavaCVCL(boolean createPbuffer) {
this(createPbuffer ? getDefaultGLCapabilities(null) : null, null, null);
}
public JavaCVCL(GLContext shareWith) {
this(getDefaultGLCapabilities(shareWith == null ? null :
shareWith.getGLDrawable().getGLProfile()), shareWith, null);
}
public JavaCVCL(GLCapabilitiesImmutable caps, GLContext shareWith, CLDevice device) {
// GLPbuffer pbuffer = null;
// if (caps != null) {
// GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
// if (factory.canCreateGLPbuffer(null, caps.getGLProfile())) {
// try {
// // makes a new buffer
// pbuffer = factory.createGLPbuffer(null, caps, null, 32, 32, shareWith);
// // required for drawing to the buffer
// pbuffer.createContext(shareWith).makeCurrent();
// } catch (GLException e) {
// logger.warning("Could not create PBuffer: " + e);
// }
// } else {
// logger.warning("OpenGL implementation does not support PBuffers.");
// }
// }
// this.pbuffer = pbuffer;
GLContext glContext = GLContext.getCurrent();
if (device == null && glContext != null) {
// woohoo! we have a GLContext
// find gl compatible device
CLDevice[] devices = CLPlatform.getDefault().listCLDevices();
for (CLDevice d : devices) {
if(d.isGLMemorySharingSupported()) {
device = d;
break;
}
}
// if(null==device) {
// throw new RuntimeException("couldn't find any CL/GL memory sharing devices ..");
// }
}
if (glContext != null && device != null) {
// create OpenCL context before creating any OpenGL objects
// you want to share with OpenCL (AMD driver requirement)
context = CLGLContext.create(glContext, device);
glu = GLU.createGLU();
} else if (device != null) {
context = CLContext.create(device);
glu = null;
} else {
// find a CL implementation
//CLPlatform platform = CLPlatform.getDefault(/*type(CPU)*/);
context = CLContext.create(/*platform.getMaxFlopsDevice()*/);
device = context.getDevices()[0];
glu = null;
}
// creade a command queue with benchmarking flag set
commandQueue = device.createCommandQueue(/*Mode.PROFILING_MODE*/);
CLKernel[] kernels = buildKernels(fastCompilerOptions, "JavaCV.cl", "pyrDown", "remap", "remapBayer");
this.pyrDownKernel = kernels[0];
this.remapKernel = kernels[1];
this.remapBayerKernel = kernels[2];
}
public void release() {
if (!context.isReleased()) {
context.release();
// if (pbuffer != null) {
// pbuffer.getContext().makeCurrent();
// pbuffer.getContext().release();
// pbuffer.getContext().destroy();
// pbuffer.destroy();
// }
}
}
@Override protected void finalize() throws Throwable {
super.finalize();
release();
}
public static final String fastCompilerOptions = // "-cl-nv-verbose " +
CompilerOptions.FAST_RELAXED_MATH + " " + CompilerOptions.ENABLE_MAD;
private static final Logger logger = Logger.getLogger(JavaCVCL.class.getName());
// private final GLPbuffer pbuffer;
private final CLContext context;
private final CLCommandQueue commandQueue;
private final GLU glu;
private final CLKernel pyrDownKernel, remapKernel, remapBayerKernel;
public CLContext getCLContext() {
return context;
}
public CLCommandQueue getCLCommandQueue() {
return commandQueue;
}
public CLGLContext getCLGLContext() {
return context instanceof CLGLContext ? (CLGLContext)context : null;
}
public GLContext getGLContext() {
return context instanceof CLGLContext ? ((CLGLContext)context).getGLContext() : null;
}
public GL getGL() {
GLContext glContext = getGLContext();
return glContext != null ? glContext.getGL() : null;
}
public GL2 getGL2() {
GL gl = getGL();
return gl != null ? gl.getGL2() : null;
}
public GLU getGLU() {
return glu;
}
public CLKernel buildKernel(String resourceNames, String kernelName) {
return buildKernels(fastCompilerOptions, Loader.getCallerClass(2), resourceNames, kernelName)[0];
}
public CLKernel buildKernel(String compilerOptions, String resourceNames, String kernelName) {
return buildKernels(compilerOptions, Loader.getCallerClass(2), resourceNames, kernelName)[0];
}
public CLKernel[] buildKernels(String compilerOptions, String resourceNames, String ... kernelNames) {
return buildKernels(compilerOptions, Loader.getCallerClass(2), resourceNames, kernelNames);
}
public CLKernel[] buildKernels(String compilerOptions, Class resourceClass, String resourceNames, String ... kernelNames) {
try {
//load and compile program for the chosen device
InputStream s;
String[] a = resourceNames.split(":");
if (a.length == 1) {
s = resourceClass.getResourceAsStream(a[0]);
} else {
Vector vs = new Vector(a.length);
for (String name : a) {
vs.addElement(resourceClass.getResourceAsStream(name));
}
s = new SequenceInputStream(vs.elements());
}
CLProgram program = context.createProgram(s);
//System.out.println("Building " + resourceNames + "...");
program.build(compilerOptions);
//System.out.println(program.getBuildLog());
assert program.isExecutable();
// create kernel and set function parameters
CLKernel[] kernels = new CLKernel[kernelNames.length];
for (int i = 0; i < kernelNames.length; i++) {
kernels[i] = program.createCLKernel(kernelNames[i]);
}
return kernels;
} catch(IOException ex) {
throw (Error)new LinkageError(ex.toString()).initCause(ex);
}
}
public CLImage2d createCLImageFrom(IplImage image, CLImage2d.Mem ... flags) {
int width = image.width();
int height = image.height();
int pitch = image.widthStep();
ByteBuffer buffer = image.getByteBuffer();
ChannelOrder order = null;
ChannelType type = null;
int size = 0;
switch (image.depth()) {
case IPL_DEPTH_8S: type = ChannelType.SNORM_INT8; size = 1; break;
case IPL_DEPTH_8U: type = ChannelType.UNORM_INT8; size = 1; break;
case IPL_DEPTH_16S: type = ChannelType.SNORM_INT16; size = 2; break;
case IPL_DEPTH_16U: type = ChannelType.UNORM_INT16; size = 2; break;
case IPL_DEPTH_32S: type = ChannelType.SIGNED_INT32; size = 4; break;
case IPL_DEPTH_32F: type = ChannelType.FLOAT; size = 4; break;
default: assert false;
}
switch (image.nChannels()) {
case 1: order = ChannelOrder.LUMINANCE; break;
case 2: order = ChannelOrder.RG; size *= 2; break;
case 3: order = ChannelOrder.RGB; size *= 3; break;
case 4: order = ChannelOrder.RGBA; size *= 4; break;
default: assert false;
}
// NVIDIA drivers do not like it when width != pitch/size
if (width != pitch/size) {
width = pitch/size;
}
CLImageFormat format = new CLImageFormat(order, type);
return context.createImage2d(buffer, width, height, /*pitch,*/ format, flags);
}
public CLGLImage2d createCLGLImageFrom(IplImage image, CLImage2d.Mem ... flags) {
GL2 gl = getGL2();
if (gl == null) {
return null;
}
int width = image.width();
int height = image.height();
int pitch = image.widthStep();
//ByteBuffer buffer = image.getByteBuffer();
int format = 0;
int size = 0;
switch (image.nChannels()) {
case 1:
switch (image.depth()) {
case IPL_DEPTH_8S: format = GL2.GL_LUMINANCE8_SNORM; size = 1; break;
case IPL_DEPTH_8U: format = GL2.GL_LUMINANCE8; size = 1; break;
case IPL_DEPTH_16S: format = GL2.GL_LUMINANCE16_SNORM; size = 2; break;
case IPL_DEPTH_16U: format = GL2.GL_LUMINANCE16; size = 2; break;
case IPL_DEPTH_32S: format = GL2.GL_LUMINANCE32I; size = 4; break;
case IPL_DEPTH_32F: format = GL2.GL_LUMINANCE32F; size = 4; break;
default: assert false;
}
break;
case 2:
switch (image.depth()) {
case IPL_DEPTH_8S: format = GL2.GL_RG8_SNORM; size = 2; break;
case IPL_DEPTH_8U: format = GL2.GL_RG8; size = 2; break;
case IPL_DEPTH_16S: format = GL2.GL_RG16_SNORM; size = 4; break;
case IPL_DEPTH_16U: format = GL2.GL_RG16; size = 4; break;
case IPL_DEPTH_32S: format = GL2.GL_RG32I; size = 8; break;
case IPL_DEPTH_32F: format = GL2.GL_RG32F; size = 8; break;
default: assert false;
}
break;
case 3:
switch (image.depth()) {
case IPL_DEPTH_8S: format = GL2.GL_RGB8_SNORM; size = 3; break;
case IPL_DEPTH_8U: format = GL2.GL_RGB8; size = 3; break;
case IPL_DEPTH_16S: format = GL2.GL_RGB16_SNORM; size = 6; break;
case IPL_DEPTH_16U: format = GL2.GL_RGB16; size = 6; break;
case IPL_DEPTH_32S: format = GL2.GL_RGB32I; size = 12; break;
case IPL_DEPTH_32F: format = GL2.GL_RGB32F; size = 12; break;
default: assert false;
}
break;
case 4:
switch (image.depth()) {
case IPL_DEPTH_8S: format = GL2.GL_RGBA8_SNORM; size = 4; break;
case IPL_DEPTH_8U: format = GL2.GL_RGBA8; size = 4; break;
case IPL_DEPTH_16S: format = GL2.GL_RGBA16_SNORM; size = 8; break;
case IPL_DEPTH_16U: format = GL2.GL_RGBA16; size = 8; break;
case IPL_DEPTH_32S: format = GL2.GL_RGBA32I; size = 16; break;
case IPL_DEPTH_32F: format = GL2.GL_RGBA32F; size = 16; break;
default: assert false;
}
break;
default: assert false;
}
// NVIDIA drivers do not like it when width != pitch/size
if (width != pitch/size) {
width = pitch/size;
}
int[] renderBuffer = new int[1];
gl.glGenRenderbuffers(1, renderBuffer, 0);
gl.glBindRenderbuffer(GL2.GL_RENDERBUFFER, renderBuffer[0]);
gl.glRenderbufferStorage(GL2.GL_RENDERBUFFER, format, width, height);
return getCLGLContext().createFromGLRenderbuffer(renderBuffer[0], flags);
}
public void releaseCLGLImage(CLGLImage2d image) {
image.release();
getGL2().glDeleteRenderbuffers(1, new int[] { image.getGLObjectID() }, 0);
}
@SuppressWarnings("unchecked")
public CLBuffer createPinnedBuffer(int size) {
// as per NVIDIA's OpenCL Best Practices Guide
CLBuffer pinnedBuffer = context.createBuffer(size, CLMemory.Mem.ALLOCATE_BUFFER);
ByteBuffer byteBuffer = commandQueue.putMapBuffer(pinnedBuffer, CLMemory.Map.READ_WRITE, true);
pinnedBuffer.use(byteBuffer);
return pinnedBuffer;
}
class PinnedIplImage extends IplImage {
PinnedIplImage(int width, int height, int depth, int channels) {
super(cvCreateImageHeader(new CvSize().width(width).height(height), depth, channels));
pinnedBuffer = createPinnedBuffer(imageSize());
imageData(new BytePointer(getByteBuffer()));
}
final CLBuffer pinnedBuffer;
public CLBuffer getCLBuffer() {
return pinnedBuffer;
}
@Override public ByteBuffer getByteBuffer() {
return (ByteBuffer)pinnedBuffer.getBuffer();
}
@Override public void release() {
commandQueue.putUnmapMemory(pinnedBuffer, getByteBuffer());
pinnedBuffer.release();
cvReleaseImageHeader(this);
}
}
public IplImage createPinnedIplImage(int width, int height, int depth, int channels) {
return new PinnedIplImage(width, height, depth, channels);
}
public IplImage createIplImageFrom(CLImage2d image) {
int width = image.width;
int height = image.height;
CLImageFormat format = image.getFormat();
ChannelOrder order = format.getImageChannelOrder();
ChannelType type = format.getImageChannelDataType();
int depth = 0, channels = 0;
switch (order) {
case R:
case A:
case INTENSITY:
case LUMINANCE:
channels = 1;
break;
case Rx:
case RG:
case RA:
channels = 2;
break;
case RGx:
case RGB:
channels = 3;
break;
case RGBx:
case RGBA:
case ARGB:
case BGRA:
channels = 4;
break;
default: assert false;
}
switch (type) {
case SIGNED_INT8:
case SNORM_INT8: depth = IPL_DEPTH_8S; break;
case UNSIGNED_INT8:
case UNORM_INT8: depth = IPL_DEPTH_8U; break;
case SIGNED_INT16:
case SNORM_INT16: depth = IPL_DEPTH_16S; break;
case UNSIGNED_INT16:
case UNORM_INT16: depth = IPL_DEPTH_16U; break;
case UNSIGNED_INT32:
case SIGNED_INT32: depth = IPL_DEPTH_32S; break;
case FLOAT: depth = IPL_DEPTH_32F; break;
case HALF_FLOAT:
case UNORM_SHORT_565:
case UNORM_SHORT_555:
case UNORM_INT_101010:
default: assert false;
}
return IplImage.create(width, height, depth, channels);
//return createPinnedIplImage(width, height, depth, channels);
}
@SuppressWarnings("unchecked")
public IplImage readImage(CLImage2d clImg, IplImage iplImage, boolean blocking) {
if (iplImage == null) {
iplImage = createIplImageFrom(clImg);
}
int x = 0, y = 0;
int width = clImg.width;
int height = clImg.height;
int pitch = iplImage.widthStep();
ByteBuffer buffer = iplImage.getByteBuffer();
IplROI roi = iplImage.roi();
if (roi != null) {
x = roi.xOffset();
y = roi.yOffset();
width = roi.width();
height = roi.height();
int pixelSize = iplImage.nChannels()*((iplImage.depth()&~IPL_DEPTH_SIGN)/8);
buffer = iplImage.getByteBuffer(y*pitch + x*pixelSize);
}
clImg.use(buffer);
commandQueue.putReadImage(clImg, pitch, x, y, width, height, blocking);
return iplImage;
}
@SuppressWarnings("unchecked")
public CLImage2d writeImage(CLImage2d clImg, IplImage iplImage, boolean blocking) {
if (clImg == null) {
clImg = createCLImageFrom(iplImage);
}
int x = 0, y = 0;
int width = iplImage.width();
int height = iplImage.height();
int pitch = iplImage.widthStep();
ByteBuffer buffer = iplImage.getByteBuffer();
IplROI roi = iplImage.roi();
if (roi != null) {
x = roi.xOffset();
y = roi.yOffset();
width = roi.width();
height = roi.height();
int pixelSize = iplImage.nChannels()*((iplImage.depth()&~IPL_DEPTH_SIGN)/8);
buffer = iplImage.getByteBuffer(y*pitch + x*pixelSize);
}
clImg.use(buffer);
commandQueue.putWriteImage(clImg, pitch, x, y, width, height, blocking);
return clImg;
}
public void acquireGLObject(CLObject object) {
if (object instanceof CLGLObject) {
commandQueue.putAcquireGLObject((CLGLObject)object);
}
}
public void releaseGLObject(CLObject object) {
if (object instanceof CLGLObject) {
commandQueue.putReleaseGLObject((CLGLObject)object);
}
}
public void readBuffer(CLBuffer> buffer, boolean blocking) {
commandQueue.putReadBuffer(buffer, blocking);
}
public void writeBuffer(CLBuffer> buffer, boolean blocking) {
commandQueue.putWriteBuffer(buffer, blocking);
}
public void executeKernel(CLKernel kernel,
long globalWorkOffsetX, long globalWorkSizeX, long localWorkSizeX) {
commandQueue.put1DRangeKernel(kernel,
globalWorkOffsetX, globalWorkSizeX, localWorkSizeX);
}
public void executeKernel(CLKernel kernel,
long globalWorkOffsetX, long globalWorkSizeX, long localWorkSizeX, CLEventList events) {
commandQueue.put1DRangeKernel(kernel,
globalWorkOffsetX, globalWorkSizeX, localWorkSizeX, events);
}
public void executeKernel(CLKernel kernel,
long globalWorkOffsetX, long globalWorkSizeX, long localWorkSizeX,
CLEventList condition, CLEventList events) {
commandQueue.put1DRangeKernel(kernel,
globalWorkOffsetX, globalWorkSizeX, localWorkSizeX, condition, events);
}
public void executeKernel(CLKernel kernel,
long globalWorkOffsetX, long globalWorkOffsetY,
long globalWorkSizeX, long globalWorkSizeY,
long localWorkSizeX, long localWorkSizeY) {
commandQueue.put2DRangeKernel(kernel,
globalWorkOffsetX, globalWorkOffsetY,
globalWorkSizeX, globalWorkSizeY,
localWorkSizeX, localWorkSizeY);
}
public void executeKernel(CLKernel kernel,
long globalWorkOffsetX, long globalWorkOffsetY,
long globalWorkSizeX, long globalWorkSizeY,
long localWorkSizeX, long localWorkSizeY, CLEventList events) {
commandQueue.put2DRangeKernel(kernel,
globalWorkOffsetX, globalWorkOffsetY,
globalWorkSizeX, globalWorkSizeY,
localWorkSizeX, localWorkSizeY, events);
}
public void executeKernel(CLKernel kernel,
long globalWorkOffsetX, long globalWorkOffsetY,
long globalWorkSizeX, long globalWorkSizeY,
long localWorkSizeX, long localWorkSizeY,
CLEventList condition, CLEventList events) {
commandQueue.put2DRangeKernel(kernel,
globalWorkOffsetX, globalWorkOffsetY,
globalWorkSizeX, globalWorkSizeY,
localWorkSizeX, localWorkSizeY, condition, events);
}
public void executeKernel(CLKernel kernel,
long globalWorkOffsetX, long globalWorkOffsetY, long globalWorkOffsetZ,
long globalWorkSizeX, long globalWorkSizeY, long globalWorkSizeZ,
long localWorkSizeX, long localWorkSizeY, long localWorkSizeZ) {
commandQueue.put3DRangeKernel(kernel,
globalWorkOffsetX, globalWorkOffsetY, globalWorkOffsetZ,
globalWorkSizeX, globalWorkSizeY, globalWorkSizeZ,
localWorkSizeX, localWorkSizeY, localWorkSizeZ);
}
public void executeKernel(CLKernel kernel,
long globalWorkOffsetX, long globalWorkOffsetY, long globalWorkOffsetZ,
long globalWorkSizeX, long globalWorkSizeY, long globalWorkSizeZ,
long localWorkSizeX, long localWorkSizeY, long localWorkSizeZ, CLEventList events) {
commandQueue.put3DRangeKernel(kernel,
globalWorkOffsetX, globalWorkOffsetY, globalWorkOffsetZ,
globalWorkSizeX, globalWorkSizeY, globalWorkSizeZ,
localWorkSizeX, localWorkSizeY, localWorkSizeZ, events);
}
public void executeKernel(CLKernel kernel,
long globalWorkOffsetX, long globalWorkOffsetY, long globalWorkOffsetZ,
long globalWorkSizeX, long globalWorkSizeY, long globalWorkSizeZ,
long localWorkSizeX, long localWorkSizeY, long localWorkSizeZ,
CLEventList condition, CLEventList events) {
commandQueue.put3DRangeKernel(kernel,
globalWorkOffsetX, globalWorkOffsetY, globalWorkOffsetZ,
globalWorkSizeX, globalWorkSizeY, globalWorkSizeZ,
localWorkSizeX, localWorkSizeY, localWorkSizeZ, condition, events);
}
public void finish() {
commandQueue.finish();
}
public void flush() {
commandQueue.flush();
}
public static int alignCeil(int x, int n) {
return (x + n-1)/n*n;
}
public static int alignFloor(int x, int n) {
return x/n*n;
}
public void pyrDown(CLImage2d srcImg, CLImage2d dstImg) {
CLEventList list = null;//new CLEventList(1);
pyrDownKernel.putArg(srcImg).putArg(dstImg).rewind();
executeKernel(pyrDownKernel, 0, 0, alignCeil(dstImg.width, 2), alignCeil(dstImg.height, 64), 2, 64, list); // execute program
// finish();
// CLEvent event = list.getEvent(0);
// System.out.println("pyrDown: " + (event.getProfilingInfo(CLEvent.ProfilingCommand.END) -
// event.getProfilingInfo(CLEvent.ProfilingCommand.START))/1000000.0);
}
public void remap(CLImage2d srcImg, CLImage2d dstImg, CLImage2d mapxImg, CLImage2d mapyImg) {
remap(srcImg, dstImg, mapxImg, mapyImg, -1L);
}
public void remap(CLImage2d srcImg, CLImage2d dstImg, CLImage2d mapxImg, CLImage2d mapyImg, long sensorPattern) {
CLEventList list = null;//new CLEventList(1);
CLKernel kernel;
if (sensorPattern != -1L) {
kernel = remapBayerKernel.putArg(srcImg).putArg(dstImg).putArg(mapxImg).putArg(mapyImg).putArg(sensorPattern).rewind();
} else {
kernel = remapKernel.putArg(srcImg).putArg(dstImg).putArg(mapxImg).putArg(mapyImg).rewind();
}
executeKernel(kernel, 0, 0, alignCeil(dstImg.width, 2), alignCeil(dstImg.height, 64), 2, 64, list); // execute program
// finish();
// CLEvent event = list.getEvent(0);
// System.out.println("remap: " + (event.getProfilingInfo(CLEvent.ProfilingCommand.END) -
// event.getProfilingInfo(CLEvent.ProfilingCommand.START))/1000000.0);
}
public static void main(String[] args) {
JavaCVCL context = new JavaCVCL();
CLImageFormat[] formats = context.getCLContext().getSupportedImage2dFormats();
for (CLImageFormat f : formats) {
System.out.println(f);
}
CameraDevice camera = new CameraDevice("Camera");
camera.imageWidth = 1280;
camera.imageHeight = 960;
camera.cameraMatrix = CvMat.create(3, 3);
double f = camera.imageWidth*2.5;
camera.cameraMatrix.put(f, 0.0, camera.imageWidth /2,
0.0, f, camera.imageHeight/2,
0.0, 0.0, 1);
camera.R = CvMat.create(3, 3);
cvSetIdentity(camera.R);
camera.T = CvMat.create(3, 1);
cvSetZero(camera.T);
camera.distortionCoeffs = CvMat.create(1, 4);
cvSetZero(camera.distortionCoeffs);
camera.distortionCoeffs.put(0.2);
camera.colorMixingMatrix = CvMat.create(3, 3);
cvSetIdentity(camera.colorMixingMatrix);
IplImage srcImg = cvLoadImageRGBA(args[0]);
//IplImage dstImg = srcImg.clone();
IplImage downDst = IplImage.create(srcImg.width()/2, srcImg.height()/2, IPL_DEPTH_8U /*IPL_DEPTH_32F*/, 4);
camera.setFixedPointMaps(false);
camera.setMapsPyramidLevel(1);
IplImage mapxImg = camera.getUndistortMap1();
IplImage mapyImg = camera.getUndistortMap2();
long start = System.nanoTime();
cvRemap(srcImg, downDst, mapxImg, mapyImg, CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS, CvScalar.ZERO);
System.out.println("cvRemap: " + (System.nanoTime()-start)/1000000.0);
cvSaveImage("/tmp/opencv.png", downDst);
CLImage2d src = context.createCLImageFrom(srcImg);
// CLImage2d dst = context.createCLImageFrom(dstImg);
CLImage2d dst = context.createCLImageFrom(downDst);
CLImage2d mapx = context.createCLImageFrom(mapxImg);
CLImage2d mapy = context.createCLImageFrom(mapyImg);
context.writeImage(src, srcImg, false);
context.writeImage(mapx, mapxImg, false);
context.writeImage(mapy, mapyImg, false);
//context.pyrDown(src, dst);
context.remap(src, dst, mapx, mapy);
context.readImage(dst, downDst, true);
//cvConvertScale(downDst, downDst, 255, 0);
cvSaveImage("/tmp/javacvcl.png", downDst);
context.release();
System.exit(0);
}
}