I am rewriting Python code into Java code (Android) and I don't know how to perform the function .shape on an image.
Python:
def getProcessedImage(srcImage):
image = copy.copy(srcImage)
print ("image.shape"), image.shape
r = 600.0 / image.shape[1]
dim = (600, int(image.shape[0] * r))
print ("dimension ="), dim
Java:
public Mat getProcessedImage(srcImage) {
Mat image = new Mat(srcImage);
srcImage.copyTo(image);
Object[] truple = new Object[Array.getLength(srcImage)] //Got stuck here and don't even think its correct
// Mat processedImage =.......
return processedImage;
}
The equivalent in java to shape in python is srcImage.size().width and srcImage.size().height.
Related
There was such a problem: working with some * .tiff, when trying to get DataRaster [] using the readDataRaster () method in the NASA WorldWind library class GeotiffReader, an exception is thrown:
ERROR j.l.Throwable - java.io.IOException: TIFF file is missing a
required tagStripOffsets
Below is the code that works with * .tiff.
Code:
private GeotiffReader reader;
private ByteBufferRaster raster;
...
reader = new GeotiffReader(file);
listDataRaster.add(reader.readDataRaster());
...
DataRaster[] dataRaster = listDataRaster.get(iter);
raster = (ByteBufferRaster)dataRaster[0];
...
raster.setDoubleAtPosition(y, x, value);
The error occurs in the line:
listDataRaster.add(reader.readDataRaster());
The method tries to return a DataRaster[] and gives the above error.
My task is to take the * .tiff ByteBufferRaster and then use setDoubleAtPosition to make changes to the grid after some calculations and rewrite * .tiff. How do I fix this error? And if not, are there other ways to accomplish my task?
Thank you all, we demand to solve this way via ExtendedGDALDataRaster
DataRasterReaderFactory readerFactory = (DataRasterReaderFactory) WorldWind
.createConfigurationComponent(AVKey.DATA_RASTER_READER_FACTORY_CLASS_NAME);
DataRasterReader dataRasterReader;
DataRaster[] dataRasters = null;
...
dataRasterReader = readerFactory.findReaderFor(file, null);
dataRasters = dataRasterReader.read(file, null);
...
rasterGdal = (ExtendedGDALDataRaster) dataRasters[0];
ElevationModel elevationModelFromGlobe = GLOBE.getElevationModel();
Sector boundingSector = rasterGdal.getSector();
int[] heightAndWidth = new int[2];
// Method for creating an empty sector by analogy with the current one
recalculationHeightAndWidth (boundingSector, elevationModelFromGlobe, heightAndWidth);
// Method to create default parameters for the sector
AVList params = getParams(boundingSector, heightAndWidth[1], heightAndWidth[0]);
raster = (ByteBufferRaster) ByteBufferRaster.createGeoreferencedRaster(params);
Dataset dataset = rasterGdal.getBestSuitedDataset(heightAndWidth[1], heightAndWidth[0], rasterGdal.getSector());
band = dataset.GetRasterBand(1);
And then for you can get the value of the height of any point from * .tiff and change it to your discretion (it will be in data)
float[] data = new float[1];
band.ReadRaster(x, y, 1, 1, band.getDataType(), data);
I am using this code in MATLAB R2015a:
javaaddpath('javacv.jar');
import org.bytedeco.javacv.*;
grabber = FrameGrabber.createDefault(0);
grabber.start();
img = grabber.grab();
And I got img variable that is org.bytedeco.javacv.Frame class.
How I convert this class to matlab image?
EDIT
I have half way through:
I Convert from org.bytedeco.javacv.Frame to org.bytedeco.javacpp.opencv_core$Mat
in this code:
javaaddpath('javacv.jar');
import org.bytedeco.javacv.*;
import org.bytedeco.javacpp.*;
import org.bytedeco.javacpp.opencv_highgui.*;
grabber = FrameGrabber.createDefault(0);
grabber.start();
img = grabber.grab();
buff = img.image(1);
bytePointer = BytePointer(buff);
cvImage = javaObject('org.bytedeco.javacpp.opencv_core$Mat',img.imageHeight,img.imageWidth,opencv_core.CV_8UC3);
cvImage = cvImage.data(bytePointer);
imshow('tal',cvImage);
I can able to see correctly the image from imshow function.
Still I want to convert from org.bytedeco.javacpp.opencv_core$Ma to matlab image.
How I can do it?
Able to convert it in inefficient way,
Put the code here, hopefully someone will convert it to efficient way code,
and publish here as an answer.
javaaddpath('javacv.jar');
import org.bytedeco.javacv.*;
import org.bytedeco.javacpp.*;
grabber = FrameGrabber.createDefault(0)
grabber.start();
img = grabber.grab();
buff = img.image(1);
w = img.imageWidth;
h = img.imageHeight;
%// from here is inefficient code
charBuff = buff.asCharBuffer;
n = charBuff.length;
data = repmat(uint16(0),n,1);
for i=0:n-1
data(i+1) = charBuff.get(i);
end
I = typecast(data, 'uint8');
I = cat(3, ...
reshape(I(3:3:end),[w h])', ...
reshape(I(2:3:end),[w h])', ...
reshape(I(1:3:end),[w h])' ...
);
imshow(I);
Faster way, still inefficient.
I think there is no more efficient way to do it, unless you write your own java code, that give you that byte array, because matlab give only duplicate of primitive array on function call, and not the array it self. the function can modified the array, but matlab do not duplicate the output when it done.
Read the "before last" comment in Problem on defining Java int array in Matlab
javaaddpath('javacv.jar');
import org.bytedeco.javacv.*;
import org.bytedeco.javacpp.*;
grabber = FrameGrabber.createDefault(0)
grabber.start();
img = grabber.grab();
buff = img.image(1);
w = img.imageWidth;
h = img.imageHeight;
%// from here is inefficient code
doubleBuff = buff.asDoubleBuffer;
n = doubleBuff.remaining;
data = zeros(n,1);
for i=1:n
data(i) = doubleBuff.get();
end
I = typecast(data, 'uint8');
I = cat(3, ...
reshape(I(3:3:end),[w h])', ...
reshape(I(2:3:end),[w h])', ...
reshape(I(1:3:end),[w h])' ...
);
imshow(I);
Faster way, still inefficient.
I think there is no more efficient way to do it, unless you write your own java code, that give you that byte array, because matlab give only duplicate of primitive array on function call, and not the array it self. the function can modified the array, but matlab do not duplicate the output when it done.
Read the "before last" comment in Problem on defining Java int array in Matlab
javaaddpath('javacv.jar');
import org.bytedeco.javacv.*;
import org.bytedeco.javacpp.*;
grabber = FrameGrabber.createDefault(0)
grabber.start();
img = grabber.grab();
buff = img.image(1);
w = img.imageWidth;
h = img.imageHeight;
%// from here is inefficient code
doubleBuff = buff.asDoubleBuffer;
n = doubleBuff.remaining;
data = zeros(n,1);
for i=1:n
data(i) = doubleBuff.get();
end
I = typecast(data, 'uint8');
I = cat(3, ...
reshape(I(3:3:end),[w h])', ...
reshape(I(2:3:end),[w h])', ...
reshape(I(1:3:end),[w h])' ...
);
imshow(I);
I'm trying to implement a DCT code in Android. I'm testing out using the code but just changing to DCT instead of DFT : Convert OpenCv DFT example from C++ to Android. There have been changes to the code, thanks to timegalore. Now I'm having problems converting the image back to BGR.
public void transformImage(){
image = Highgui.imread(imageName, Highgui.CV_LOAD_IMAGE_GRAYSCALE);
try {
secondImage = new Mat(image.rows(), image.cols(), CvType.CV_64FC1);
image.convertTo(secondImage, CvType.CV_64FC1);
int m = Core.getOptimalDFTSize(image.rows());
int n = Core.getOptimalDFTSize(image.cols()); // on the border add zero values
Mat padded = new Mat(new Size(n, m), CvType.CV_64FC1); // expand input image to optimal size
Imgproc.copyMakeBorder(secondImage, padded, 0, m - secondImage.rows(), 0, n - secondImage.cols(), Imgproc.BORDER_CONSTANT);
Mat result = new Mat(padded.size(), padded.type());
Core.dct(padded, result);
Mat transformedImage = new Mat(padded.size(), padded.type());
Core.idct(result, watermarkedImage);
completedImage = new Mat(image.rows(), image.cols(), CvType.CV_64FC1);
Imgproc.cvtColor(transformedImage, completedImage, Imgproc.COLOR_GRAY2BGR);
} catch (Exception e) {
Log.e("Blargh", e.toString());
}
}
Now, I have obtained this error
04-09 21:35:52.362: E/cv::error()(23460): OpenCV Error: Assertion failed (depth == CV_8U || depth == CV_16U || depth == CV_32F) in void cv::cvtColor(cv::InputArray, cv::OutputArray, int, int), file /home/reports/ci/slave_desktop/50-SDK/opencv/modules/imgproc/src/color.cpp, line 3642
I am not sure what I should do, please advise. Your help is very much appreciated!
You have this line:
image.convertTo(secondImage, CvType.CV_64FC1);
but then you don't use secondImage again, just image. Try:
Imgproc.copyMakeBorder(secondImage, padded, 0, m - secondImage.rows(), 0, n - secondImage.cols(), Imgproc.BORDER_CONSTANT);
and see how you get on.
Also DCT looks like it only works on reals not complex numbers like DFT and so you don't need to add a second channel to zero the imaginary part. You can work directly with the padded variable, so:
Mat result = new Mat(padded.size(), padded.type());
then
Core.dct(padded, result);
also, the original image needs to be single channel - so a greyscale. When you call Highgui.imread the image that will be loaded is multichannel - on my device it is 3 channel in BGR format. You can convert it to greyscale using Imgproc.cvtColor but it would be simpler just to load it as grey scale in the first place:
image = Highgui.imread(imageName, Highgui.CV_LOAD_IMAGE_GRAYSCALE);
I was practicing on some face recognition and detection codes using Java on JavaCv on Eclpise Juno. The Thing is i was trying to run the sample code below but i cant get the expected result or output. The sample code is as follows
import com.googlecode.javacpp.Loader;
import com.googlecode.javacv.*;
import com.googlecode.javacv.cpp.*;
import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
import static com.googlecode.javacv.cpp.opencv_calib3d.*;
import static com.googlecode.javacv.cpp.opencv_objdetect.*;
public class Demo {
public static void main(String[] args) throws Exception {
String classifierName = null;
if (args.length > 0) {
classifierName = args[0];
} else {
System.err.println("C://opencv/data/haarcascades\"haarcascade_frontalface_alt.xml\".");
System.exit(1);
}
// Preload the opencv_objdetect module to work around a known bug.
Loader.load(opencv_objdetect.class);
// We can "cast" Pointer objects by instantiating a new object of the desired class.
CvHaarClassifierCascade classifier = new CvHaarClassifierCascade(cvLoad(classifierName));
if (classifier.isNull()) {
System.err.println("Error loading classifier file \"" + classifierName + "\".");
System.exit(1);
}
// CanvasFrame is a JFrame containing a Canvas component, which is hardware accelerated.
// It can also switch into full-screen mode when called with a screenNumber.
CanvasFrame frame = new CanvasFrame("Some Title");
// OpenCVFrameGrabber uses opencv_highgui, but other more versatile FrameGrabbers
// include DC1394FrameGrabber, FlyCaptureFrameGrabber, OpenKinectFrameGrabber,
// PS3EyeFrameGrabber, VideoInputFrameGrabber, and FFmpegFrameGrabber.
FrameGrabber grabber = new OpenCVFrameGrabber(0);
grabber.start();
// FAQ about IplImage:
// - For custom raw processing of data, getByteBuffer() returns an NIO direct
// buffer wrapped around the memory pointed by imageData.
// - To get a BufferedImage from an IplImage, you may call getBufferedImage().
// - The createFrom() factory method can construct an IplImage from a BufferedImage.
// - There are also a few copy*() methods for BufferedImage<->IplImage data transfers.
IplImage grabbedImage = grabber.grab();
int width = grabbedImage.width();
int height = grabbedImage.height();
IplImage grayImage = IplImage.create(width, height, IPL_DEPTH_8U, 1);
IplImage rotatedImage = grabbedImage.clone();
// Let's create some random 3D rotation...
CvMat randomR = CvMat.create(3, 3), randomAxis = CvMat.create(3, 1);
// We can easily and efficiently access the elements of CvMat objects
// with the set of get() and put() methods.
randomAxis.put((Math.random()-0.5)/4, (Math.random()-0.5)/4, (Math.random()-0.5)/4);
cvRodrigues2(randomAxis, randomR, null);
double f = (width + height)/2.0; randomR.put(0, 2, randomR.get(0, 2)*f);
randomR.put(1, 2, randomR.get(1, 2)*f);
randomR.put(2, 0, randomR.get(2, 0)/f); randomR.put(2, 1, randomR.get(2, 1)/f);
System.out.println(randomR);
// Objects allocated with a create*() or clone() factory method are automatically released
// by the garbage collector, but may still be explicitly released by calling release().
// You shall NOT call cvReleaseImage(), cvReleaseMemStorage(), etc.
//on objects allocated this way.
CvMemStorage storage = CvMemStorage.create();
// We can allocate native arrays using constructors taking an integer as argument.
CvPoint hatPoints = new CvPoint(3);
// Again, FFmpegFrameRecorder also exists as a more versatile alternative.
FrameRecorder recorder = new OpenCVFrameRecorder("output.avi", width, height);
recorder.start();
while (frame.isVisible() && (grabbedImage = grabber.grab()) != null) {
cvClearMemStorage(storage);
// Let's try to detect some faces! but we need a grayscale image...
cvCvtColor(grabbedImage, grayImage, CV_BGR2GRAY);
CvSeq faces = cvHaarDetectObjects(grayImage, classifier, storage,
1.1, 3, CV_HAAR_DO_CANNY_PRUNING);
int total = faces.total();
for (int i = 0; i < total; i++) {
CvRect r = new CvRect(cvGetSeqElem(faces, i));
int x = r.x(), y = r.y(), w = r.width(), h = r.height();
cvRectangle(grabbedImage, cvPoint(x, y), cvPoint(x+w, y+h), CvScalar.RED, 1, CV_AA, 0);
// To access the elements of a native array, use the position() method.
hatPoints.position(0).x(x-w/10) .y(y-h/10);
hatPoints.position(1).x(x+w*11/10).y(y-h/10);
hatPoints.position(2).x(x+w/2) .y(y-h/2);
cvFillConvexPoly(grabbedImage, hatPoints.position(0), 3, CvScalar.GREEN, CV_AA, 0);
}
// Let's find some contours! but first some thresholding...
cvThreshold(grayImage, grayImage, 64, 255, CV_THRESH_BINARY);
// To check if an output argument is null we may call either isNull() or equals(null).
CvSeq contour = new CvSeq(null);
cvFindContours(grayImage, storage, contour, Loader.sizeof(CvContour.class),
CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
while (contour != null && !contour.isNull()) {
if (contour.elem_size() > 0) {
CvSeq points = cvApproxPoly(contour, Loader.sizeof(CvContour.class),
storage, CV_POLY_APPROX_DP, cvContourPerimeter(contour)*0.02, 0);
cvDrawContours(grabbedImage, points, CvScalar.BLUE, CvScalar.BLUE, -1, 1, CV_AA);
}
contour = contour.h_next();
}
cvWarpPerspective(grabbedImage, rotatedImage, randomR);
frame.showImage(rotatedImage);
recorder.record(rotatedImage);
}
recorder.stop();
grabber.stop();
frame.dispose();
}
}
The Output i am getting is a line printed in red and its like.
C://opencv/data/haarcascades"haarcascade_frontalface_alt.xml".
Can anybody show what i missed?
I am new to image processing and so please can anyone indicate me where i could get good tutorials and sample source codes that could teach me how to master all the in-built functions in JavaCv and their functionalities? I was working on my final year project and really need your hand on this one.
With lots of respect
Sisay
haarcascade_frontalface_alt.xml is trained classifier for detecting frontal face. It is usually present in opencv_installation_folder/opencv/data/haarcascade folder. you can give the direct path of your classifier instead of taking it from command line as
classifierName = opencv_installation_folder/opencv/data/harcascade/haarcascade_frontalface_alt.xml
that demo expects you to give it the cascade-file as an argument. it just stops, if it does not get one.
maybe you want to change the beginning like this:
public class Demo {
public static void main(String[] args) throws Exception {
String classifierName = "C:/opencv/data/haarcascades/haarcascade_frontalface_alt.xml";
if (args.length > 0) {
classifierName = args[0];
}
like that, it takes an arg from cmdline if present, else it takes the default-value
I'm creating a program in Java that will interface with a C library to take images from hardware and display with OpenGL (using JOGL). So the workflow is this:
Hardware -> C -> disk image file -> Java -> JOGL
I have the Java -> JOGL part working fine. The images are displayed fully and I can load multiple images at a time. I also have the Hardware -> C working as well, and a temporary viewer in C is showing that the images are being created just fine.
The crux of the problem is this: I want to be able to launch the main() method of the Java program in C and then display the image using only JNI code in C (using static methods I've created). However, when I do this, the image is truncated, where I only get the top 20 or so rows. I do know that I'm loading the entire image because I can check the pixel values for every pixel in the image. Only the display is truncated. The same number of pixels are shown for every image I load.
This is the C code in a nutshell:
int main () { ...
HMODULE * jvm_dll;
//HWND hWnd = GetConsoleWindow();
//ShowWindow( hWnd, SW_HIDE );
env = create_vm(&jvm, jvm_dll);
if (env == NULL) { return 1; }
//Create a new String array with one blank String
cls = (*env)->FindClass(env,"java/lang/String");
arg = (*env)->NewStringUTF(env,"");
args = (jobjectArray)(*env)->NewObjectArray(env, 1, cls, arg);
//Call the main method with the String array argument
cls = (*env)->FindClass(env, "path/to/package/program");
mID = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V");
(*env)->CallStaticVoidMethod(env, cls, mID, args);
PrintStackTrace(env);
blockAndClose(jvm, env, jvm_dll);
return ret;
}
int blockAndClose() {...
int ret = 0;
if (jvm == 0 || env == 0) {
FreeLibrary(*jvm_dll);
return 1;
}
ret = (*jvm)->DestroyJavaVM(jvm);
if(jvm_dll) {
FreeLibrary(*jvm_dll);
jvm_dll = 0;
}
env = 0;
jvm = 0;
return ret;
}
I know that I've only posted the C portion, but the Java portion is working when I run it purely in Java. At this point, the C portion is simply a "launcher" of sorts, so I'm wondering why it affects the running of the code. Any suggestions?
EDIT:
Here's the code for loading images. I use JAI to load in the image as a PlanarImage type (TiledImage class is a subclass).
tempI = JAI.create("fileload", path);
DataBufferUShort dbOut = null;
ColorModel CM = PlanarImage.getDefaultColorModel(DataBuffer.TYPE_USHORT, tempI.getNumBands());
SampleModel SM = CM.createCompatibleSampleModel(tempI.getWidth(), tempI.getHeight());
//Ensure that the buffer is in the internal format (USHORT)
if (tempI.getData().getDataBuffer().getDataType() != DataBuffer.TYPE_USHORT) {
DataBuffer dBIn = tempI.getData().getDataBuffer();
short [] dBPixels = new short[dBIn.getSize()];
switch(dBIn.getDataType()) {
case DataBuffer.TYPE_BYTE:
DataBufferByte dBByte = (DataBufferByte)dBIn;
byte [] pByte = dBByte.getData();
for (int b = 0; b < pByte.length; b++)
{ dBPixels[b] = (short)((double)pByte[b] / 0xFF * 0xFFFF); }
dbOut = new DataBufferUShort(dBPixels, dBPixels.length);
break;
case DataBuffer.TYPE_SHORT:
DataBufferShort dBShort = (DataBufferShort)dBIn;
dBPixels = dBShort.getData();
dbOut = new DataBufferUShort(dBPixels, dBPixels.length);
break;
} //SWITCH DATA TYPE --END
WritableRaster rs = Raster.createWritableRaster(SM, dbOut, new Point(0,0));
tempI = new TiledImage(0,0,tempI.getWidth(),tempI.getHeight(),0,0,SM,CM);
((TiledImage)tempI).setData(rs);
}