I am trying to achieve EigenFace Recognition in JavaCV and implementing it through this code:-
public static void main(String[] args) {
String trainingDir = "C:/Users/user/Documents/NetBeansProjects/Face/testimg";
IplImage testImage = cvLoadImage("C:/Users/user/Desktop/aa.png");
File root = new File(trainingDir);
FilenameFilter pngFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".png");
}
};
File[] imageFiles = root.listFiles(pngFilter);
MatVector images = new MatVector(imageFiles.length);
int[] labels = new int[imageFiles.length];
int counter = 0;
int label;
IplImage img;
IplImage grayImg = null;
try {
for (File image : imageFiles) {
img = cvLoadImage(image.getAbsolutePath(), CV_BGR2GRAY);
int yer = image.getName().indexOf(".");
String isim = image.getName().substring(0, yer);
label = Integer.parseInt(isim);
images.put(counter, img);
labels[counter] = label;
counter++;
}
} catch (Exception e) {
e.printStackTrace();
}
IplImage greyTestImage = IplImage.create(testImage.width(), testImage.height(), IPL_DEPTH_8U, 1);
//FaceRecognizer faceRecognizer = createFisherFaceRecognizer();
FaceRecognizer faceRecognizer = createEigenFaceRecognizer();
//FaceRecognizer faceRecognizer = createLBPHFaceRecognizer()
faceRecognizer.train(images, labels);
cvCvtColor(testImage, greyTestImage, CV_BGR2GRAY);
int predictedLabel = faceRecognizer.predict(greyTestImage);
System.out.println("Predicted label: " + predictedLabel);
}
But each time I run it,It gives me an error
OpenCV Error: Image step is wrong (The matrix is not continuous, thus its number of rows can not be changed) in cv::Mat::reshape, file ........\opencv\modules\core\src\matrix.cpp, line 802
Exception in thread "main" java.lang.RuntimeException: ........\opencv\modules\core\src\matrix.cpp:802: error: (-13) The matrix is not continuous, thus its number of rows can not be changed in function cv::Mat::reshape
I have read some where that it happens when Images are not of same size and not a multiple of 8,but i have all the images of same size and grayscaled too.The code i used for saving detected Face is:-
Mat image_roi = new Mat(frame,rect_Crop);
Imgproc.cvtColor(image_roi, image_roi, Imgproc.COLOR_BGR2GRAY);
Size sz = new Size(240,240);
Imgproc.resize( image_roi, image_roi, sz );
String filename = "testimg\\" +jTextField1.getText() + ".png";
System.out.println(String.format("Writing %s", filename));
Imgcodecs.imwrite(filename, image_roi);
It also gives me
java.lang.NumberFormatException:
for my files don't know why.....???
Please help....!!!!
Related
I'm new to coding environment, I'm working in an imaging processing project - I have a video file of n size and I'm trying to find a mean and standard deviation of (Height, width and number of frames)that file . the image file(imgfile_500) is in MAT
here is my code
public class Image_conv {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
String filePath = "C:\\Video_500.h264";
if (!Paths.get(filePath).toFile().exists()){
System.out.println("File " + filePath + " does not exist!");
return;
}
VideoCapture video500 = new VideoCapture(filePath);
if (!video500.isOpened()) {
System.out.println("Error! video500 can't be opened!");
return;
}
int ntime=20;
int fps= 60;
int ds_fac=4;
int nf = (ntime*fps);
int wd_ds = 480/ds_fac;
int hg_ds = 640/ds_fac;
int vsize = wd_ds*hg_ds*nf;
Mat frame = new Mat(480,640,CvType.CV_64FC3);
Mat frame500 = new Mat(480,640,CvType.CV_64FC3);
Mat imgfile_500 = new Mat();
if (video500.isOpened()) {
while(true){
if (video500.read(frame))
{
Imgproc.cvtColor(frame, frame500, Imgproc.COLOR_RGB2GRAY);
//System.out.println(frame500.size());
Imgproc.pyrDown( frame500, frame500, new Size( frame500.cols()/2, frame500.rows()/2 ) );
Imgproc.pyrDown( frame500, frame500, new Size( frame500.cols()/2, frame500.rows()/2 ) );
// Imgcodecs.imwrite(i+"led500.jpg", frame500);
// Push a Mat back into MatVector
imgfile_500.push_back(frame500);
}else break;
}
}
//System.out.println(imgfile_500.size());
}
}
I'm trying to find an image that I create previously inside an empty template with this function that insert text on it receiving color, content and font and return the path of generate image:
the template
public String insertTextOnBlanck(String colorLetter,String text,Font font) {
//path is a private varibable initialized with the constructor
File blankFile = new File("images/dinamic/"+path);
BufferedImage image = null;
String exit_path = null;
try {
image = ImageIO.read(blankFile);
int type = image.getType() == 0? BufferedImage.TYPE_INT_ARGB : image.getType();
Graphics2D g2 = image.createGraphics();
FontMetrics metrics = g2.getFontMetrics(font);
BufferedImage resizeImage = resizeImage(image,type, text,metrics);
image.flush();
int w = resizeImage.getWidth();
int h = resizeImage.getHeight();
g2 = resizeImage.createGraphics();
g2.setColor(Color.decode(colorLetter));
g2.setFont(font);
// Get the FontMetrics
int x = (w - metrics.stringWidth(text)) / 2;
int y = (metrics.getAscent() + (h - (metrics.getAscent() + metrics.getDescent())) / 2);
g2.setBackground(Color.decode("#d1e8f8"));
g2.drawString(text, x, y);
g2.dispose();
//create image with text
exit_path = "images/dinamic/changed_"+path;
File file = new File(exit_path);
ImageIO.write(resizeImage, "png", file);
resizeImage.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return exit_path;
}
and this works the fist time when i call this other function
public void dinamicClick(String path,String input,String fontLetter,String colorLetter, int fontType,int size) throws FindFailed {
DinamicImg DimImg = new DinamicImg();
DimImg.setPath(path);
String modPath = DimImg.insertTextOnBlanck(
colorLetter,
input,//Inventario de recurso
new Font(fontLetter,fontType, size)
);
Iterator<Match> myIt = s.findAll(modPath);
while (myIt.hasNext()) {
Location loc = myIt.next().getTarget();
s.click(loc);
}
myIt.remove();
removeFile(modPath);
}
the removeFile function is:
private void removeFile(String toRemove) {
File file = new File(toRemove);
if(file.delete()){
System.out.println(file.getName() + " is deleted!");
}else{
System.out.println("Delete operation is failed.");
}
}
The result:
but next calls dont work at all, just when i change the name of exit path, so i thought was a cache problem but adding ImageIO.setUseCache(false); at start of "insertTextOnBlanck" function still doesn`t work. Im out of ideas please help, thanks.
I resolve it , with the libary org.sikuli.script.ImagePath you ve to reset the paths of the internal cache of SikuliX with ImagePath.reset().
In the class getPathGiveIcon, am passing an array of strings to getPaths() method. This getPaths() is expected to return an array of ImageIcons. In this process, am trying to create a file out of a every path name in the array of strings but at this line am getting error.
img[i] = ImageIO.read(fa);// in this line the error
Kindly guide me to over come this error...
Here is full code of the getPaths() method.
public class GetPathGiveIcon {
ImageIcon[] iic;
File f = new File(" ");
int i = 0;
public ImageIcon[] getPaths(String[] s)
{
BufferedImage[] img = null;
for(String st : s)
{
System.out.println(st);
}
for(String st : s)
try
{
{
File fa = new File(st);
img[i] = ImageIO.read(fa);
System.out.println(" inside try block the value of every string = " + st);
}
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println(" Value of I before scaling " + i);
i = 0;
for(BufferedImage bi : img)
{
iic[i] = new ImageIcon(bi);
Image scaled = iic[i].getImage().getScaledInstance(150,150,
Image.SCALE_DEFAULT);
iic[i] = new ImageIcon(scaled);
i++;
}
System.out.println(" Value of I after scaling " + i);
return iic;
}
}
That is because
BufferedImage[] img = null;
You have to initialize img array with
BufferedImage[] img = new BufferedImage[s.length];
i always equals 0 so your code will only fill the first element of your array.
Here is the solution :
BufferedImage[] img = new BufferedImage[s.length];
for(String st : s)
{
try
{
File fa = new File(st);
img[i++] = ImageIO.read(fa);
System.out.println(" inside try block the value of every string = " + st);
}
catch(Exception e)
{
e.printStackTrace();
}
}
edit
Same issue with iic, it has to be initialized
iic = new ImageIcon[img.length];
i = 0;
for(BufferedImage bi : img)
{
iic[i] = new ImageIcon(bi);
// [...]
I m having a sample image(sorry for the type of image) which i m feeding into JAI code to get a compressed image.
Now the output image i m getting is in mono-color. I don't know why is the output is abnormal but other images are getting processed just fine.
The sample original and processed images are -
Original Image -
Processed Image -
The JAI code to process the image -
private static final String JAI_STREAM_ACTION = "stream";
private static final String JAI_SUBSAMPLE_AVERAGE_ACTION = "SubsampleAverage";
private static final String JAI_ENCODE_FORMAT_JPEG = "JPEG";
private static final String JAI_ENCODE_ACTION = "encode";
private static final String JPEG_CONTENT_TYPE = "image/jpeg";
private int mMaxWidth = 800;
//private int mMaxWidthThumbnail = 150;
private byte[] resizeImageAsJPG(byte[] pImageData, int pMaxWidth) throws IOException {
InputStream imageInputStream = new ByteArrayInputStream(pImageData);
SeekableStream seekableImageStream = SeekableStream.wrapInputStream(imageInputStream, true);
RenderedOp originalImage = JAI.create(JAI_STREAM_ACTION, seekableImageStream);
((OpImage) originalImage.getRendering()).setTileCache(null);
int origImageWidth = originalImage.getWidth();
double scale = 1.0;
/*
if (pMaxWidth > 0 && origImageWidth > pMaxWidth) {
scale = (double) pMaxWidth / originalImage.getWidth();
} */
ParameterBlock paramBlock = new ParameterBlock();
paramBlock.addSource(originalImage); // The source image
paramBlock.add(scale); // The xScale
paramBlock.add(scale); // The yScale
paramBlock.add(0.0); // The x translation
paramBlock.add(0.0); // The y translation
RenderingHints qualityHints = new RenderingHints(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
RenderedOp resizedImage = JAI.create(JAI_SUBSAMPLE_AVERAGE_ACTION, paramBlock, qualityHints);
BufferedImage scaledImage = null ;
ByteArrayOutputStream encoderOutputStream = new ByteArrayOutputStream();
JAI.create(JAI_ENCODE_ACTION, resizedImage, encoderOutputStream, JAI_ENCODE_FORMAT_JPEG, null);
//byte[] resizedImageByteArray = encoderOutputStream.toByteArray();
System.out.println("This is from exiting JAI");
return encoderOutputStream.toByteArray();
}
With imgScalr I m also getting the same output.
In openJDK with JAI I get the error -
javax.media.jai.util.ImagingException: All factories fail for the operation "encode"
With imgScalr in openJDK-
javax.imageio.IIOException: Invalid argument to native writeImage
Any other library i can use in java to get the desired result.
Regards
The solution is to convert the image to 3Byte_BGR -
private synchronized BufferedImage getScaledImage1(BufferedImage imageBytes)
{
BufferedImage scaledImage = null;
int type = 0;
try
{
type = imageBytes.getType();
if(type == 0 || type ==6) {
int w = imageBytes.getWidth();
int h = imageBytes.getHeight();
BufferedImage newImage =
new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR);
Graphics2D g = newImage.createGraphics();
g.drawImage(imageBytes, 0, 0, null);
g.dispose();
imageBytes = newImage;
}
scaledImage = Scalr.resize(imageBytes, Scalr.Method.ULTRA_QUALITY,2000,
Scalr.OP_ANTIALIAS);
} catch(Exception e) {
}
return scaledImage;
}
I'm trying to implement animated textures into an OpenGL game seamlessly. I made a generic ImageDecoder class to translate any BufferedImage into a ByteBuffer. It works perfectly for now, though it doesn't load animated images.
I'm not trying to load an animated image as an ImageIcon. I need the BufferedImage to get an OpenGL-compliant ByteBuffer.
How can I load every frames as a BufferedImage array in an animated image ?
On a similar note, how can I get the animation rate / period ?
Does Java handle APNG ?
The following code is an adaption from my own implementation to accommodate the "into array" part.
The problem with gifs is: There are different disposal methods which have to be considered, if you want this to work with all of them. The code below tries to compensate for that. For example there is a special implementation for "doNotDispose" mode, which takes all frames from start to N and paints them on top of each other into a BufferedImage.
The advantage of this method over the one posted by chubbsondubs is that it does not have to wait for the gif animation delays, but can be done basically instantly.
BufferedImage[] array = null;
ImageInputStream imageInputStream = ImageIO.createImageInputStream(new ByteArrayInputStream(data)); // or any other source stream
Iterator<ImageReader> imageReaders = ImageIO.getImageReaders(imageInputStream);
while (imageReaders.hasNext())
{
ImageReader reader = (ImageReader) imageReaders.next();
try
{
reader.setInput(imageInputStream);
frames = reader.getNumImages(true);
array = new BufferedImage[frames];
for (int frameId : frames)
{
int w = reader.getWidth(0);
int h = reader.getHeight(0);
int fw = reader.getWidth(frameId);
int fh = reader.getHeight(frameId);
if (h != fh || w != fw)
{
GifMeta gm = getGifMeta(reader.getImageMetadata(frameId));
// disposalMethodNames: "none", "doNotDispose","restoreToBackgroundColor","restoreToPrevious",
if ("doNotDispose".equals(gm.disposalMethod))
{
image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) image.getGraphics();
for (int f = 0; f <= frameId; f++)
{
gm = getGifMeta(reader.getImageMetadata(f));
if ("doNotDispose".equals(gm.disposalMethod))
{
g.drawImage(reader.read(f), null, gm.imageLeftPosition, gm.imageTopPosition);
}
else
{
// XXX "Unimplemented disposalMethod (" + getName() + "): " + gm.disposalMethod);
}
}
g.dispose();
}
else
{
image = reader.read(frameId);
// XXX "Unimplemented disposalMethod (" + getName() + "): " + gm.disposalMethod;
}
}
else
{
image = reader.read(frameId);
}
if (image == null)
{
throw new NullPointerException();
}
array[frame] = image;
}
}
finally
{
reader.dispose();
}
}
return array;
private final static class GifMeta
{
String disposalMethod = "none";
int imageLeftPosition = 0;
int imageTopPosition = 0;
int delayTime = 0;
}
private GifMeta getGifMeta(IIOMetadata meta)
{
GifMeta gm = new GifMeta();
final IIOMetadataNode gifMeta = (IIOMetadataNode) meta.getAsTree("javax_imageio_gif_image_1.0");
NodeList childNodes = gifMeta.getChildNodes();
for (int i = 0; i < childNodes.getLength(); ++i)
{
IIOMetadataNode subnode = (IIOMetadataNode) childNodes.item(i);
if (subnode.getNodeName().equals("GraphicControlExtension"))
{
gm.disposalMethod = subnode.getAttribute("disposalMethod");
gm.delayTime = Integer.parseInt(subnode.getAttribute("delayTime"));
}
else if (subnode.getNodeName().equals("ImageDescriptor"))
{
gm.imageLeftPosition = Integer.parseInt(subnode.getAttribute("imageLeftPosition"));
gm.imageTopPosition = Integer.parseInt(subnode.getAttribute("imageTopPosition"));
}
}
return gm;
}
I don't think Java supports APNG by default, but you can use an 3rd party library to parse it:
http://code.google.com/p/javapng/source/browse/trunk/javapng2/src/apng/com/sixlegs/png/AnimatedPngImage.java?r=300
That might be your easiest method. As for getting the frames from an animated gif you have to register an ImageObserver:
new ImageIcon( url ).setImageObserver( new ImageObserver() {
public void imageUpdate( Image img, int infoFlags, int x, int y, int width, int height ) {
if( infoFlags & ImageObserver.FRAMEBITS == ImageObserver.FRAMEBITS ) {
// another frame was loaded do something with it.
}
}
});
This loads asynchronously on another thread so imageUpdate() won't be called immediately. But it will be called for each frame as it parses it.
http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/ImageObserver.html