Tensorflow on Java: how to perform RGB to BGR operation? - java

I need to convert my 3-D tensor containing RGB image to BGR.
All the sources I've found on the web use python and they refer to operations that are either absent or different on java:
reverse does not accept an index but a boolean as second input
I've found the stack/unstack method, but unstack does not exist

Stack and Unstack operations are actually called as they have previously been on the other platforms, that is, Pack and Unpack. *
So, to perform the requested operation of transforming a Tensor representing an image in RGB to an image in BGR, the unstack/stack way can be followed.
public <T> Output<T> rgbToBgr(Output<T> input) {
return stackReverted(unstack(input));
}
// where g is Graph
public <T> Output<T>[] unstack(Output<T> input) {
return (Output<T>[]) g.opBuilder("Unpack", "Unpack")
.addInput(input)
.setAttr("axis", -1)
.setAttr("num", 3)
.build().outputList(0, 3);
}
public <T> Output<T> stackReverted(Output<T>[] input){
GraphOperationBuilder graphOperationBuilder = g.opBuilder("Pack", "Pack")
.setAttr("axis", -1);
Output<T>[] newInput = Arrays.copyOf(input, input.length);
for (int i = 0; i < input.length; i++)
newInput[i] = input[input.length - 1 - i];
graphOperationBuilder.addInputList(newInput);
return graphOperationBuilder.build().output(0);
}
There is no trace anywhere. If anybody can find documentation for Java, please post it.

Related

eval function in C resulting in negative

I am using java 11, Eclipse IDE.
I am designing a program that needs some calculations, I am writing that program in java, so I was trying to find something similar to a function called "eval()", which evaluates an equation. So, I implemented that function in C and turned it into a ".dll" file and used it inside java.
My main problem is when I pass the equation into the eval function, and it returns a double which is negative and very huge, like : I passed it "1.0+0.5^2", and it resulted "-9.255963134931783E61", it is impossible to get to a result like that!
NOTE : it has always returned the right result, but at the last piece of execution, it has returned the above! Why? How? I am using the same eval function.
I will only show you the important parts and leave the rest, which is not important :
All codes :
eval.c :
int evaluate(char* line, double* val);
static int do_op(void);
static int do_paren(void);
static void push_op(char op);
static void push_arg(double arg);
static STATUS pop_arg(double* arg);
static STATUS pop_op(int* op);
static char* getexp(char* str);
static char* getop(char* str);
static char* getop(char* str);
JNIEXPORT jdouble JNICALL Java_application_Main_eval
(JNIEnv* env, jobject object, jstring str) {
const char* strs = env->GetStringUTFChars(str, false);
char* equation = const_cast<char*>(strs);
double result;
evaluate(equation, &result);
printf("the result is : %f", result);
jdouble* returnResult = new jdouble(result);
return *returnResult;
}
The native eval method in java :
static {
System.load(System.getProperty("user.dir")+"\\eval.dll");
}
public native double eval(String equation);
the java method that resulted something odd at the end :
String evaluateEquation(String e) {
// we will truncate the brackets into pieces and eval every piece,
// and then return it without brackets by replacing it inside the equation!
StringBuilder equation = new StringBuilder(e);
int count = countBrackets(equation);
int[] pos;
String part;
String result;
// TODO : fix here :
BigDecimal tempResult = new BigDecimal(0);
while (count!=0) { // every one loop, it will truncate, evaluate, replace the new value!
pos = lastBrackets(equation.toString());
part = equation.substring(pos[0], pos[1]+1);
System.out.println("evaluating this part : "+part);
tempResult = new BigDecimal(new Main().eval(part));
System.out.println(tempResult.toString());
result = truncateDecimals(tempResult);
equation.replace(pos[0], pos[1]+1, result);
System.out.println(equation.toString());
count--;
}
System.out.println(equation.substring(0, equation.length()));
part = equation.substring(0, equation.length()-1);
finalResult = new BigDecimal(new Main().eval(part));
System.out.println("FinalResult is : "+truncateDecimals(finalResult));
return truncateDecimals(finalResult);
}
If you have read the "eval.c" program, you will notice that it takes a "char*" and a "double&". I have taken care of these conversions and I think they have a relation with this bug. The method always returns the right result, except at one place, which is at the end of the "evaluateEquation" method.
Based on my knowledge, any number stored inside the computer memory gets to negative ONLY when we change it to a negative OR it extends on its maximum number to store. if the number breaks its limit, it will turn into a negative.
However, I noticed something, the number that is negative is being repeated again and again every time I call the eval function in the end of the "evaluateEquation" function I get the same result, which is : "-9.255963134931783E61".
If you have any assumptions, explanation or anything. Please, feel free to talk. I will never down-vote anyone who is trying to help me.
NOTE : this is the original C code that I used to make the dll file : http://stjarnhimlen.se/snippets/eval.c
The number -9.255963134931783E61 has the internal representation 0xCCCCCCCCCCCCCCCC, which strongly suggests that it is an uninitialised value.
Since you don't check the return value from evaluate, that suggests that it is returning an error condition, because in that case, evaluate does notset the value pointed to by its second argument.
I have noticed that the code is missing something. I revised it, and I remembered that a dll file is only loaded once when the program starts, so all the variables are being deleted or cleaned up. That caused the returned value to be odd and repeated continuously after the used arrays are full. So, I created a function to clear :
void clear() {
for (int i = 0; i!=256 ; i++) {
op_stack[i] = NULL;
arg_stack[i] = NULL;
token[i] = NULL;
}
op_sptr = 0;
arg_sptr = 0;
parens = 0;
state = 0;
}

Junit did not show any results using IntelliJ for UCB cs61B (org.junit.Assert.assertArrayEquals() )

I am studying CS61B - UCB on my own, and I am a beginner in using IntelliJ and Junit4.12. I found there is no result for my org.junit.Assert.assertArrayEquals()
while in the video there is something shows like this
in the Run Window.
Here is the code for TestSort.java
import static org.junit.Assert.*;
import org.junit.Test;
/** Tests the the Sort class. */
public class TestSort {
/** Test the Sort.sort method. */
#Test
public void testSort() {
String[] input = {"i", "have", "an", "egg"};
String[] expected = {"an", "egg", "have", "i"};
Sort.sort(input);
if (input != expected)
{
System.out.println("something wrong!");
}
org.junit.Assert.assertArrayEquals(expected, input);
}
#Test
public void testFindSmallest() {
String[] input = {"i", "have", "an", "egg"};
int expected = 2;
int actual = Sort.findSmallest(input, 0);
assertEquals(expected, actual);
String[] input2 = {"there", "are", "many", "pigs"};
int expected2 = 2;
int actual2 = Sort.findSmallest(input2, 2);
assertEquals(expected2, actual2);
}
#Test
public void testSwap() {
String[] input = {"i", "have", "an", "egg"};
int a = 0;
int b = 2;
String[] expected = {"an", "have", "i", "egg"};
Sort.swap(input, a, b);
assertArrayEquals(expected, input);
}
}
Here is the code for Sort.java
public class Sort {
public static void sort(String[] x) {
sort(x, 0);
}
private static void sort(String[] x, int start) {
if (start == x.length) {
return;
}
int smallestIndex = findSmallest(x, start);
swap(x, start, smallestIndex);
sort(x, start + 1);
}
public static void swap(String[] x, int a, int b) {
String temp = x[a];
x[a] = x[b];
x[b] = temp;
}
public static int findSmallest(String[] x, int start) {
int smallestIndex = start;
for (int i = start; i < x.length; i += 1) {
int cmp = x[i].compareTo(x[smallestIndex]);
if (cmp < 0) {
smallestIndex = i;
}
}
return smallestIndex;
}
}
I think the function for Junit is to get the green part which shows how my codes work and get the result of whether two of my Strings are equal or not.
Another question about the IntelliJ is whether there is any difference between I RUN it and using the terminal to compile and operate it? Because when I use terminal, it will show something like this
enter image description here
I have googled a lot about this, it always said like I did not applied the Junit.jar into classpath. I have checked I have added the library.enter image description here
fyi, the you can get the library here enter link description here
I debugged the testSort function and it goes well for the input part and the sort functions part. while it gives me the hint that enter image description here, I chosed Download, it showed sources not found enter image description here, and when I chose sources from exist files enter image description here, it keeps attaching....How can I solve this problem?
You're code may not be running as you expected, but it is running exactly as a more experienced Java dev would expect. Let me explain...
You've discovered the behavior of the = operator (or more precisely in this case, !=) that often trips up less experienced Java engineers. The = operator doesn't know how to work with arrays so it falls back to comparing references. In your case it is comparing input and expected to see if they reference the exact same object. In your code both input and expected are declared as new arrays and therefor are different, individual objects; they do not reference the same object.
As for assertArrayEquals it likely doesn't use the = operator at all. While I haven't looked at the source code for that method I'd venture to guess that it first checks reference equality (are they both referencing the same object, then checks to see if they are both arrays and then checks to see whether each element of expected is also in input.
Arrays can add to the equality confusion because there are many definitions of equality. Equality could be defined as...
both arrays having the same number of elements in the same order
both arrays having the same number of elements, but different order
one array having 5 elements while the other having 10 elements where all 5 elements of the first array are also in the second array
etc.
One suggestion I have that might help you better understand this issue (as well as many more issues you are likely to face in the future) is to look at the source code of the method that's not working as you expect it to work, assertArrayEquals in this case. IntelliJ allows you to navigate to the source code, or if the source code is not available, look at the decompiled byte code. On a Mac just Command-click on the method. In Windows it might be Control-click??? (sorry, IntelliJ has so many different shortcut sets I can't be more specific.)
Further info on this topic...
What is the difference between == vs equals() in Java?
https://javabeginnerstutorial.com/core-java-tutorial/java-equals-method-vs-operator/

How to feed boolean placeholder by means of TensorFlowInferenceInterface.java?

I'm trying to launch trained in Keras Tensorflow graph by means of Java Tensorflow API.
Aside from standard input image placeholder, this graph contains 'keras_learning_phase' placeholder that is needed to be fed with a boolean value.
The thing is, there is no method in TensorFlowInferenceInterface for boolean values - you can only feed it with float, double, int or byte values.
Obviously, when I try to pass int to this tensor by means of this code:
inferenceInterface.fillNodeInt("keras_learning_phase",
new int[]{1}, new int[]{0});
I get
tensorflow_inference_jni.cc:207 Error during inference: Internal:
Output 0 of type int32 does not match declared output type bool for
node _recv_keras_learning_phase_0 = _Recvclient_terminated=true,
recv_device="/job:localhost/replica:0/task:0/cpu:0",
send_device="/job:localhost/replica:0/task:0/cpu:0",
send_device_incarnation=4742451733276497694,
tensor_name="keras_learning_phase", tensor_type=DT_BOOL,
_device="/job:localhost/replica:0/task:0/cpu:0"
Is there a way to circumvent it?
Maybe it is possible somehow to explicitly convert Placeholder node in graph to Constant?
Or maybe it is possible to initially avoid creation of this Placeholder in the graph?
The TensorFlowInferenceInterface class essentially is a convenience wrapper over the full TensorFlow Java API, which does support boolean values.
You could perhaps add a method to TensorFlowInferenceInterface to do what you want. Similar to fillNodeInt, you could add the following (note the caveat that booleans in TensorFlow are represented as one byte):
public void fillNodeBool(String inputName, int[] dims, bool[] src) {
byte[] b = new byte[src.length];
for (int i = 0; i < src.length; ++i) {
b[i] = src[i] ? 1 : 0;
}
addFeed(inputName, Tensor.create(DatType.BOOL, mkDims(dims), ByteBuffer.wrap(b)));
}
Hope that helps. If it works, I'd encourage you to contribute back to the TensorFlow codebase.
This is in addition to the answer by ash, as the Tensorflow API has changed a little. Using this worked for me:
public void feed(String inputName, boolean[] src, long... dims) {
byte[] b = new byte[src.length];
for (int i = 0; i < src.length; i++) {
b[i] = src[i] ? (byte) 1 : (byte) 0;
}
addFeed(inputName, Tensor.create(Boolean.class, dims, ByteBuffer.wrap(b)));
}

Fixing the Aztec decoder in Zxing (Obj-C) to return raw ByteArray

I'm working on an iOS app that's supposed to decode a certain type of Aztec barcode (example, PDF). I need the scanner to return the data on a low level, since it's zlib compressed and I need to decompress it afterwards. The built-in barcode scanner using AVCapture works fine for regular string data but fails in my case.
I have turned to Zxing, or rather its Objective C port ZXingObjC, in the hope of being able to access the decoded barcode data before it gets turned into a string. I was half successful. The ZXResult returned does contain a ZXByteArray called rawBytes, but only for QR codes (for Aztec codes it's nil)! I looked inside ZXAztecDecoder.m and sure enough, the byte array is never populated, not even in the original Zxing code in Java.
Someone tried to fix it for the original library (Pull Request, Line 80) by doing
byte[] rawBytes = convertBoolArrayToByteArray(correctedBits);
I'd like to add the same functionality for ZXingObjC, but I'm stuck trying to convert theZXBoolArray to a ZXByteArray. Here is the decode function as I envision it:
- (ZXDecoderResult *)decode:(ZXAztecDetectorResult *)detectorResult error:(NSError **)error {
self.ddata = detectorResult;
ZXBitMatrix *matrix = [detectorResult bits];
ZXBoolArray *rawbits = [self extractBits:matrix];
if (!rawbits) {
if (error) *error = ZXFormatErrorInstance();
return nil;
}
ZXBoolArray *correctedBits = [self correctBits:rawbits error:error];
if (!correctedBits) {
return nil;
}
ZXByteArray *rawBytes = /* somehow turn correctedBits into ZXByteArray */;
NSString *result = [[self class] encodedData:correctedBits];
return [[ZXDecoderResult alloc] initWithRawBytes:rawBytes text:result byteSegments:nil ecLevel:nil];
}
If somebody knows how to do this or has an idea how to go about it, I'd appreciate it. If it works out, I'd like to contribute the code to ZXingObjC, so this won't bug people in the future. Thanks in advance!
It's not actually a solution to the problem, but my persistent nagging helped fix this overdue issue in the original ZXing Github repo. If that change makes it upstream into ZXingObjC at some point, I can close this question for good.
If anybody wants to help translate these Java lines (source) to Objective-C, I'd surely appreciate it.
/**
* Reads a code of length 8 in an array of bits, padding with zeros
*/
private static byte readByte(boolean[] rawbits, int startIndex) {
int n = rawbits.length - startIndex;
if (n >= 8) {
return (byte) readCode(rawbits, startIndex, 8);
}
return (byte) (readCode(rawbits, startIndex, n) << (8 - n));
}
/**
* Packs a bit array into bytes, most significant bit first
*/
static byte[] convertBoolArrayToByteArray(boolean[] boolArr) {
byte[] byteArr = new byte[(boolArr.length + 7) / 8];
for (int i = 0; i < byteArr.length; i++) {
byteArr[i] = readByte(boolArr, 8 * i);
}
return byteArr;
}

Java store boolean array in file and read fast

I need to store boolean array with 80,000 items in file. I don't care how much time saving takes, I'm interested only in the loading time of array.
I did't try to store it by DataOutputStream because it requires access for each value.
I tried to make this by 3 approaches, such as:
serialize boolean array
use BitSet instead of boolean array an serialize it
transfer boolean array into byte array, where 1 is true and 0 is false appropriately and write it by FileChannel using ByteBuffer
To test reading from files by these approaches, I had run each approach 1,000 times in loop. So I got results which look like this:
deserialization of boolean array takes 574 ms
deserialization of BitSet - 379 ms
getting byte array from FileChannel by MappedByteBuffer - 170 ms
The first and second approaches are too long, the third, perhaps, is not approach at all.
Perhaps there are a best way to accomplish it, so I need your advice
EDIT
Each method ran once
13.8
8.71
6.46
ms appropriatively
What about writing a byte for each boolean and develop a custom parser? This will propably one of the fastest methods.
If you want to save space you could also put 8 booleans into one byte but this would require some bit shifting operations.
Here is a short example code:
public void save() throws IOException
{
boolean[] testData = new boolean[80000];
for(int X=0;X < testData.length; X++)
{
testData[X] = Math.random() > 0.5;
}
FileOutputStream stream = new FileOutputStream(new File("test.bin"));
for (boolean item : testData)
{
stream.write(item ? 1 : 0);
}
stream.close();
}
public boolean[] load() throws IOException
{
long start = System.nanoTime();
File file = new File("test.bin");
FileInputStream inputStream = new FileInputStream(file);
int fileLength = (int) file.length();
byte[] data = new byte[fileLength];
boolean[] output = new boolean[fileLength];
inputStream.read(data);
for (int X = 0; X < data.length; X++)
{
if (data[X] != 0)
{
output[X] = true;
continue;
}
output[X] = false;
}
long end = System.nanoTime() - start;
Console.log("Time: " + end);
return output;
}
It takes about 2ms to load 80.000 booleans.
Tested with JDK 1.8.0_45
So I had a very similar use case where i wanted to serialise/deserialise a very large boolean array.
I implemented something like this,
Firstly i converted boolean array to an integer array simply to club multiple boolean values (This makes storage more efficient and there are no issues with bit padding)
This now means we have to build wrapper methods which will give true/false
private boolean get (int index) {
int holderIndex = (int) Math.floor(index/buckets);
int internalIndex = index % buckets;
return 0 != (container[holderIndex] & (1 << internalIndex));
}
and
private void set (int index) {
int holderIndex = (int) Math.floor(index/buckets);
int internalIndex = index % buckets;
int value = container[holderIndex];
int newValue = value | (1 << internalIndex);
container[holderIndex] = newValue;
}
Now to serialise and deserialise you can directly convert this to bytestream and write to file.
my source code, for reference

Categories