I'm trying to run the unit tests in the tess4j distribution currently. And while running one of the unit tests, java crashed with the following error:
TessBaseAPIGetIterator
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x6718f834, pid=5612, tid=3592
#
# JRE version: 7.0_17-b02
# Java VM: Java HotSpot(TM) Client VM (23.7-b01 mixed mode, sharing windows-x86 )
# Problematic frame:
# C [libtesseract302.dll+0xf834] tesseract::TessBaseAPI::Init+0x34
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# G:\Final year project\eclipse stuff\Testings\hs_err_pid5612.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.sun.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
Can i please get help? i'm fairly sure that the DLL file is not corrupt and neither is my harddisk. i'm using the Windows 8 OS and the latest version of eclipse to build the project.
The code is:
import java.io.File;
import net.sourceforge.tess4j.*;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.PointerByReference;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.*;
import java.util.Arrays;
import javax.imageio.ImageIO;
import net.sourceforge.tess4j.TessAPI1.*;
import net.sourceforge.vietocr.ImageIOHelper;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
public class TesseractExample{
String datapath = "G:\\Final year project\\eclipse stuff\\tessdemo\\tessdata";
String language = "eng";
String expOCRResult = "The (quick) [brown] {fox} jumps!\nOver the $43,456.78 <lazy> #90 dog";
TessAPI1.TessBaseAPI handle;
public void testResultIterator() throws Exception {
System.out.println("TessBaseAPIGetIterator");
String lang = "eng";
File tiff = new File("eurotext.tif");
BufferedImage image = ImageIO.read(new FileInputStream(tiff)); // require jai-imageio lib to read TIFF
ByteBuffer buf = ImageIOHelper.convertImageData(image);
int bpp = image.getColorModel().getPixelSize();
int bytespp = bpp / 8;
int bytespl = (int) Math.ceil(image.getWidth() * bpp / 8.0);
TessAPI1.TessBaseAPIInit3(handle, datapath, lang);
TessAPI1.TessBaseAPISetPageSegMode(handle, TessAPI1.TessPageSegMode.PSM_AUTO);
TessAPI1.TessBaseAPISetImage(handle, buf, image.getWidth(), image.getHeight(), bytespp, bytespl);
TessAPI1.TessBaseAPIRecognize(handle, null);
TessAPI1.TessResultIterator ri = TessAPI1.TessBaseAPIGetIterator(handle);
TessAPI1.TessPageIterator pi = TessAPI1.TessResultIteratorGetPageIterator(ri);
TessAPI1.TessPageIteratorBegin(pi);
System.out.println("Bounding boxes:\nchar(s) left top right bottom confidence font-attributes");
int height = image.getHeight();
do {
Pointer ptr = TessAPI1.TessResultIteratorGetUTF8Text(ri, TessAPI1.TessPageIteratorLevel.RIL_WORD);
String word = ptr.getString(0);
TessAPI1.TessDeleteText(ptr);
float confidence = TessAPI1.TessResultIteratorConfidence(ri, TessAPI1.TessPageIteratorLevel.RIL_WORD);
IntBuffer leftB = IntBuffer.allocate(1);
IntBuffer topB = IntBuffer.allocate(1);
IntBuffer rightB = IntBuffer.allocate(1);
IntBuffer bottomB = IntBuffer.allocate(1);
TessAPI1.TessPageIteratorBoundingBox(pi, TessAPI1.TessPageIteratorLevel.RIL_WORD, leftB, topB, rightB, bottomB);
int left = leftB.get();
int top = topB.get();
int right = rightB.get();
int bottom = bottomB.get();
System.out.print(String.format("%s %d %d %d %d %f", word, left, top, right, bottom, confidence));
System.out.println(String.format("%s %d %d %d %d", str, left, height - bottom, right, height - top)); // training box coordinates
IntBuffer boldB = IntBuffer.allocate(1);
IntBuffer italicB = IntBuffer.allocate(1);
IntBuffer underlinedB = IntBuffer.allocate(1);
IntBuffer monospaceB = IntBuffer.allocate(1);
IntBuffer serifB = IntBuffer.allocate(1);
IntBuffer smallcapsB = IntBuffer.allocate(1);
IntBuffer pointSizeB = IntBuffer.allocate(1);
IntBuffer fontIdB = IntBuffer.allocate(1);
String fontName = TessAPI1.TessResultIteratorWordFontAttributes(ri, boldB, italicB, underlinedB,
monospaceB, serifB, smallcapsB, pointSizeB, fontIdB);
boolean bold = boldB.get() == TessAPI1.TRUE;
boolean italic = italicB.get() == TessAPI1.TRUE;
boolean underlined = underlinedB.get() == TessAPI1.TRUE;
boolean monospace = monospaceB.get() == TessAPI1.TRUE;
boolean serif = serifB.get() == TessAPI1.TRUE;
boolean smallcaps = smallcapsB.get() == TessAPI1.TRUE;
int pointSize = pointSizeB.get();
int fontId = fontIdB.get();
System.out.println(String.format(" font: %s, size: %d, font id: %d, bold: %b," +
" italic: %b, underlined: %b, monospace: %b, serif: %b, smallcap: %b",
fontName, pointSize, fontId, bold, italic, underlined, monospace, serif, smallcaps));
} while (TessAPI1.TessPageIteratorNext(pi, TessAPI1.TessPageIteratorLevel.RIL_WORD) == TessAPI1.TRUE);
}
public static void main(String[] args) {
TesseractExample instance=new TesseractExample();
try {
instance.testResultIterator();
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}
Thank you!
Looks like handle has not been initialized.
handle = TessAPI1.TessBaseAPICreate();
Related
I need to get big Boolean arrays or BitSets from Java into Python via a text file. Ideally I want to go via a Base64 representation to stay compact, but still be able to embed the value in a CSV file. (So the boolean array will be one column in a CSV file.)
However I am having issues to get the byte alignment right. Where/how should I specify the correct byte order?
This is one example, working in the sense that it executes but not working in that my bits aren't where I want them.
Java:
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.Base64;
import java.util.Base64.Encoder;
import java.util.BitSet;
public class basictest {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Encoder b64 = Base64.getEncoder();
String name = "name";
BitSet b = new BitSet();
b.set(444);
b.set(777);
b.set(555);
byte[] bBytes = b.toByteArray();
String fp_str = b64.encodeToString(bBytes);
BufferedWriter w = new BufferedWriter(new FileWriter("out.tsv"));
w.write(name + "\t" + fp_str + "\n");
w.close();
}
}
Python:
import numpy as np
import base64
from bitstring import BitArray, BitStream ,ConstBitStream
filename = "out.tsv"
with open(filename) as file:
data = file.readline().split('\t')
b_b64 = data[1]
b_bytes = base64.b64decode(b_b64)
b_bits = BitArray(bytes=b_bytes)
b_bits[444] # False
b_bits[555] # False
b_bits[777] # False
# but
b_bits[556] # True
# it's not shifted:
b_bits[445] # False
I am now reversing the bits in every byte using https://stackoverflow.com/a/5333563/1259675:
numbits = 8
r_bytes = [
sum(1<<(numbits-1-i) for i in range(numbits) if b>>i&1)
for b in b_bytes]
b_bits = BitArray(r_bytes)
This works, but is there a method that doesn't involve myself fiddling with the bits?
If:
the maximum bit to set is "sufficiently small".
and the data, you want to encode doesn't vary in size too much.
..then one approach can be:
Set max (+ min) significant bit(s in java) .
and ignore them in python .
, then it c(sh!)ould work without byte reversal, or further transformation:
// assuming a 1024 bit word
public static final int LEFT_SIGN = 0;
public static final int RIGHT_SIGN = 1025; //choose a size, that fits your needs [0 .. Integer.MAX_VALUE - 1 (<-theoretically)]
public static void main(String[] args) throws Exception {
...
b.set(LEFT_SIGN);
b.set(444 + 1);
b.set(777 + 1);
b.set(555 + 1);
b.set(RIGHT_SIGN);
...
and then in python:
# as before ..
b_bits[0] # Ignore!
b_bits[445] # True
b_bits[556] # True
b_bits[778] # True
b_bits[1025] # Ignore!;)
Your convenience (= encoding) 'd be the (maximum) "word length" ... with all its benefits and drawbacks.
We can use the bitarray package from python for this particular usecase.
from bitarray import bitarray
import base64
with open(filename) as file:
data = file.readline().strip().split('\t')
b_b64 = data[1]
b_bytes = base64.b64decode(b_b64)
bs = bitarray(endian='little')
bs.frombytes(b_bytes)
print bs
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x5f0c25fe, pid=14780, tid=11168
#
# JRE version: Java(TM) SE Runtime Environment (7.0_80-b15) (build 1.7.0_80-b15)
# Java VM: Java HotSpot(TM) Client VM (24.80-b11 mixed mode, sharing windows-x86 )
# Problematic frame:
# C [ZBRGraphics.dll+0x25fe]
I keep getting this error when using the Zebra printer DLL in Java program.
public class Tester {
public static void main(String[] args) {
ZBRGraphics zGraphics = ZBRGraphics.INSTANCE;
String text = "Print this";
byte[] textB = text.getBytes(StandardCharsets.UTF_8);
String font= "Arial";
byte[] fontB = text.getBytes(StandardCharsets.UTF_8);
System.out.println(zGraphics.ZBRGDIDrawText(0, 0, textB, fontB, 12, 1, 0x0FF0000, 0));
}
}
public interface ZBRGraphics extends Library {
ZBRGraphics INSTANCE = (ZBRGraphics) Native.loadLibrary("ZBRGraphics", ZBRGraphics.class);
int ZBRGDIDrawText(int x, int y, byte[] text, byte[] font, int fontSize, int fontStyle, int color, int err);
}
I have the DLL in C:\Windows\System32 and in my 32 bit Java .
I'm using a 64 bit machine as my laptop for development.
If my google-fu skills are any good, you appear to be interfacing with the Zebra printer's API. According to the "ZXP1 & ZXP3 Software Developers Reference Manual" (found here), the Java mapping of the function is incorrect.
This is the actual C function prototype:
int ZBRGDIDrawText(
int x,
int y,
char *text,
char *font,
int fontSize,
int fontStyle,
int color,
int *err
)
As you can see, err is not an int, but a pointer to one. Also, since text and font are strings, you can just use a String as the Java type. Additionally, the API docs say that the return value is an int with either 1 for success or 0 for failure, meaning that you can use a boolean for ease of use.
The following Java mapping should be correct:
boolean ZBRGDIDrawText(
int x,
int y,
String text,
String font,
int fontSize,
int fontStyle,
int color,
IntByReference err
);
and you might use it like so:
IntByReference returnCode = new IntByReference(0);
boolean success = zGraphics.ZBRGDIDrawText(
0,
0,
"Print this",
"Arial",
12,
1,
0x0FF0000,
returnCode
);
if (success) {
System.out.println("success");
} else {
System.out.println("ZBRGDIDrawText failed with code " + returnCode.getValue());
}
I've got java code to call a python script
Java
private void visualizeData() {
try{
Runtime.getRuntime().exec(“python pyScripts/visualize.py”)
} catch (IOException e){
e.printStackTrace();
}
}
And this is my code for the visualize.py:
visualize.py
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pylot as plt
f = open(“ecoli_data_transformed.txt”,”r”)
fig = plt.figure()
ax = fig.add_subplot(111, projection=‘3d’)
for line in f:
(a, b, c) = line.split(“\t”)
a = float(a)
b = float(b)
c = float(c)
ax.scatter(a,b,c)
ax.setxlabel(‘PCA1’)
ax.setylabel(‘PCA2’)
ax.setzlabel(‘PCA3’)
plt.show()
But it doesn't plot the data.
If I call the test.py script from the java code (test.py is in the same directory as visualize.py), it works:
test.py
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pylot as plt
import numpy as np
np.random.seed(19680801)
def randrange(n, min, vmcx):
return (vmax - vein)*np.random.rand(n) + vmin
fig = plt.figure()
ax = fig.add_subplot(111, projection=‘3d’)
n = 100
for c, m, slow, high in [(‘r’, ‘o’, -50, -25), (‘b’, ‘^’, -30, -5)]:
xs = randrange(n, 23, 32)
ys = randrange(n, 0, 100)
zs = randrange(n, zlow, zhigh)
ax.scatter(xs, ys, zs, c=c, marker=m)
ax.set_xlabel(‘X Label’)
ax.set_ylabel(‘Y Label’)
ax.set_zlabel(‘Z Label’)
plt.show()
What could be the problem?
*NOTE: Calling the visualize.py script from console by 'python visualize.py' works totally fine.
The relative path that you are passing to the open() command in your python script is probably the problem.
Your Java program is located in a different directory than the one your Python program is located in. When it starts the python script, the current path is still the path to the Java program.
This means that Python is unable to find the relative path to the file you are trying to open, ecoli_data_transformed.txt.
A work around would be to include the complete path to your .txt file:
f = open(“C:\\path\\to\\your\\file\\ecoli_data_transformed.txt”,”r”)
A better solution would be to determine it programatically:
import os
file_path = os.path.dirname(__file__)
f = open(file_path + "\\ecoli_data_transformed.txt”,”r”)
I'm working on raycast, but I have a big problem. Here is the error message.
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f2a67b5345b, pid=19347, tid=139820316944128
#
# JRE version: OpenJDK Runtime Environment (7.0_79-b14) (build 1.7.0_79-b14)
# Java VM: OpenJDK 64-Bit Server VM (24.79-b02 mixed mode linux-amd64 compressed oops)
# Derivative: IcedTea 2.5.5
# Distribution: Custom build (Wed Apr 15 12:39:15 UTC 2015)
# Problematic frame:
# C [libgdx-box2d64.so+0x3a45b] void b2DynamicTree::RayCast<b2WorldRayCastWrapper>(b2WorldRayCastWrapper*, b2RayCastInput const&) const+0x3ab
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
You can look the log file here http://paste.ubuntu.com/11287130/
Here is my callback and splitObj.
private final RayCastCallback callback = new RayCastCallback() {
#Override
public float reportRayFixture(Fixture fixture, Vector2 point, Vector2 normal, float fraction) {
//We can just slice the field and field is ChainShape
if (fixture.getShape() instanceof ChainShape) {
Body body = fixture.getBody();
List<Vector2> pointVec = rayCastMap.get(body);
if (pointVec == null) {
pointVec = new ArrayList<Vector2>();
rayCastMap.put(body, pointVec);
}
if (!pointVec.isEmpty() && !pointVec.get(0).equals(point)) {
pointVec.add(point.cpy());
splitObj(body, pointVec);
} else {
pointVec.add(point.cpy());
}
}
return 1;
}
};
private void splitObj(Body sliceBody, List<Vector2> splitedPoints) {
Vector2 a = splitedPoints.get(0);
Vector2 b = splitedPoints.get(1);
Array<Vector2> shape1Vertices = new Array<Vector2>();
shape1Vertices.addAll(a, b);
Array<Vector2> shape2Vertices = new Array<Vector2>();
shape2Vertices.addAll(a, b);
for (Vector2 vec : field.getVertices()) {
float determinant = det(a, b, vec);
if (determinant > 0) {
if (!shape1Vertices.contains(vec, false))
shape1Vertices.add(vec);
} else if (determinant < 0) {
if (!shape2Vertices.contains(vec, false))
shape2Vertices.add(vec);
}
}
GeometryUtils.arrangeClockwise(shape1Vertices);
GeometryUtils.arrangeClockwise(shape2Vertices);
FloatArray shape1 = arrayToFloatArray(shape1Vertices);
FloatArray shape2 = arrayToFloatArray(shape2Vertices);
FloatArray newShape;
float shape1Area = calculateArea(shape1);
float shape2Area = calculateArea(shape2);
box2dWorld.destroyBody(sliceBody);
ball.box2dBall.setActive(false);
float splicedArea;
if (det(a, b, ball.getPosition()) > 0) {
splicedArea = shape2Area * 100 / (shape1Area + shape2Area);
newShape = shape1;
} else {
splicedArea = shape1Area * 100 / (shape1Area + shape2Area);
newShape = shape2;
}
field.setIsSliced(true);
// setting the properties of the two newly created shapes
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.StaticBody;
bodyDef.position.set(sliceBody.getPosition());
FixtureDef fixtureDef = new FixtureDef();
// creating the first shape
PolygonShape polygonShape = new PolygonShape();
polygonShape.set(newShape.toArray());
fixtureDef.shape = polygonShape;
sliceBody = box2dWorld.createBody(bodyDef);
sliceBody.createFixture(fixtureDef);
}
I want to slice an object(ChainShape) and there is a ball which can move around inside this chainshape.I listen touchDown , touchDragged and touchUp for input.
touchDown gets first point of the line for raycast , touchDragged gets second point of the line and touchUp is calling raycast like this one.
box2dWorld.rayCast(callback, p2, p1);
When I call that , sometimes it gives this fatal error.What is my problem? What can I do?
Usually if you see a SIGSEGV Java Runtime Environment error while working with box2d then it is related to the usage of an already destroyed body / joint etc.
Take a look at your code here you destroy a body:
box2dWorld.destroyBody(sliceBody);
Then some lines later you try to use that already destroyed body again (!):
bodyDef.position.set(sliceBody.getPosition());
You cannot use destroyed bodies anymore! Try to destroy bodies only after you are sure you are not going to use them anymore.
My Processing code is below.
import hypermedia.video.*;
import processing.video.*;
import java.awt.Rectangle;
OpenCV opencv;
int width = 320;
int height = 240;
void setup() {
size( 320, 240 ); //set window size
opencv = new OpenCV( this ); //setup openCV
opencv.capture( width, height ); // open video stream
opencv.cascade( OpenCV.CASCADE_FRONTALFACE_ALT );
}
void draw(){
opencv.read();
image(opencv.image(), 0, 0);
Rectangle[] faces = opencv.detect( 1.2, 2, OpenCV.HAAR_DO_CANNY_PRUNING, 40, 40 );
noFill();
stroke(255,0,0);
for( int i=0; i<faces.length; i++ ) {
rect( faces[i].x, faces[i].y, faces[i].width, faces[i].height );
}
}
This code works for few seconds then an exception occurs.
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x6d961b22, pid=232, tid=4008
#
# JRE version: 6.0_33-b03
# Java VM: Java HotSpot(TM) Client VM (20.8-b03 mixed mode windows-x86 )
# Problematic frame:
# V [jvm.dll+0xa1b22]
#
# An error report file with more information is saved as:
# C:\Documents and Settings\Administrator\Desktop\processing-2.0b7\hs_err_pid232.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#
i think it is a memory allocation issue with opencv_core.CvMemStorage. this is a class that's not exposed in your library. i am having the same problem. I'm using javacv (directly, not javacvpro) because i want to run multiple haar cascades (you can load only one with javacvpro or the older hypermedia.video.*). if i run ALL of them on EACH frame, i'm good. if i run a different detector on each frame (and then cycle thru the detectors again), i get this error after a few cycles.
the snippet below FAILS, but it is what i want to do (process each subsequent frame with a different detector):
// Using JavaCV directly, not JavaCVPro!
import com.googlecode.javacpp.Loader;
import com.googlecode.javacv.*;
import com.googlecode.javacv.*;
import com.googlecode.javacv.cpp.*;
String cascades[] = {
"haarcascade_eye.xml", // 0
"haarcascade_eye_tree_eyeglasses.xml", // 1
"haarcascade_frontalface_alt.xml" // 2
}
int detectors[] = {1,3};
// haar detectors to use
String cascPath = "C:/opencv/data/haarcascades/";
// preload multiple classifiers. can do this with javacvpro, not with javacv or hypermedia.video.*
void haarSetup() {
for (int i = 0; i < detectors.length; i++) {
String classifierFile = cascPath+cascades[detectors[i]];
classifier[i] =
new opencv_objdetect.CvHaarClassifierCascade(opencv_core.cvLoad(classifierFile));
}
storage = opencv_core.CvMemStorage.create();
opencv_core.cvClearMemStorage(storage); // is this needed? couldn't hurt, right?
}
// contains list of preloaded haar cascades. code not included here...
opencv_core.CvSeq features[] = new opencv_core.CvSeq[detectors.length];
int whichHaar = 0;
// run one cascade per frame, then cycle through them.
void processHaars(PImage piz) {
// convert to IplImage...
BufferedImage imgBuf = (BufferedImage) piz.getNative();
opencv_core.IplImage iplImgOut=opencv_core.IplImage.createFrom(imgBuf);
// do one haar cascade per invocation.
int ii = whichHaar;
features[ii] = opencv_objdetect.cvHaarDetectObjects(iplImgOut, classifier[ii], storage, 1.1, 3, opencv_objdetect.CV_HAAR_DO_CANNY_PRUNING);
whichHaar++;
if (whichHaar >= detectors.length){
whichHaar = 0;
// is THIS causing the problem??
opencv_core.cvClearMemStorage(storage);
}
}
this snippet WORKS forever, but i don't want what it does (run all detectors on a single frame):
void processHaars(PImage piz) {
// convert to IplImage...
BufferedImage imgBuf = (BufferedImage) piz.getNative();
opencv_core.IplImage iplImgOut=opencv_core.IplImage.createFrom(imgBuf);
for (ii=0; ii<detectors.length; ii++)
faces[ii] = opencv_objdetect.cvHaarDetectObjects(iplImgOut, classifier[ii], storage, 1.1, 3, opencv_objdetect.CV_HAAR_DO_CANNY_PRUNING);
opencv_core.cvClearMemStorage(storage);
}
If i find a full solution, I'll post it.