Fast way to access Mat from Opencv on Android? - android

I need to modify/access my mat on Android, but it is really really slow (it took about 2 minutes to run on a 3500*100 mat).
I need to set some value to 0, but not all, and I am using this line to modify it.
this.getMyMat().put(i, j, 0);
Any idea to get it a bit faster ? My code in C++ takes at least 50 times less time to run, doing this way :
((myMat.data + myMat.step*row))[j] = 0

You can use rowRange() or colRange() to extract the submatrix you wish to be zeroed out, and call setTo() to actually fill in the values. This will be faster than iterating pixel-by-pixel.
Mat rows = this.getMyMat().rowRange(0,3);
rows.setTo(new Scalar(0));

Related

OpenCV Android - Calculate the average of a column of Mat

What I'm trying is to calculate the average of a column using openCV in android.
The initial idea was to copy each column to a temp matrix, then use Core.mean() to get the average value.
But the problem is :
To use Mat.put(), it is expected to have a row, column and a Array[] data and Core.Mean() returns a scalar, so I can't do something like:
myMat.put(row,1,Core.Mean(myTempColumn)).
So how this operation can be done?
I'm wondering that I'll need to get each element from myMat using get and then sum. But the problem is get returns also a Array[] data (that I think is the RGB value), and to sum it, will be necessary another for structure (which I don't think it is the easiest way).
Thank you in advance.
Ok solve it:
Core.reduce(imageMat,averageMat,0,Core.REDUCE_AVG);
Where:
0 means that the matrix is reduced to a single row. 1 means that the matrix is reduced to a single column.
Core.REDUCE_AVG - does the average

Frame-independent animation in game developement on android

Ok so delta-time is 1/fps right? Say the fps was 50, then delta time would equal 1/50= 0.02. My question is that frame rate varies(one second it might be 50, another it might be 52). So say for one second the fps is 50, that means that delta time will be equal to 0.02, but the NEXT second the fps will be 52, but we don't know that yet. So our animations are being done with delta time of 1/50 but the fps is actually 52. Until the next second is finished we won't know that the fps has changed. This may not seem like a big deal if the changes are small, but if they become very big then we have a problem. So the thing is we are always doing calculations based on the previous second's fps. I want to know how to solve this. Thanks!
You're right that 1/fps = delta-time. However, fps isn't known at the present, and as you pointed out going about it this way would cause a problem! In practice, the formula is re-arranged such that 1/dt = fps.
So, we determine delta-time by determining how much time has passed since the last update( deltaTime = (CurrentTime - LastTime) ). If we were to have a variable that we add delta time to every every update (say, deltaCounter += deltaTime), and another variable which is a counter we add one to each update (Counter++), we would see that when deltaCounter is becomes equal to 1, the Counter variable is our fps for that second.
Further Reading on Delta Time and its Implementation

Android - Randomly setting a button in a grid

this is an extension to this question: Android - Handling a grid
Basically, I am wondering how to make a grid of 4x4 buttons randomly change their features(text, color, etc.) I don't need help setting the actual change in text or color, I just need a way to go about something like this. I don't know if I should write an array and choose from there, or use the GridView. Just a little start to something is all I need, I'm not asking for lots of code. Thanks in advance, I really appreciate it.
If your 4 ids are sequential as is
btnId1 = 8006;
btnId2 = 8007;
btnId3 = 8008;
btnId4 = 8009;
Random rn = new Random();
int chooseId = btnId1 + rn.nextInt(btnId4 - btnId1 + 1);
You can generate a random number like so:
Random r=new Random();
r.nextInt(4);
this will give you a random number in the range [0,4).
Based on this random number, you change the properties of the appropriate tile/square which you can enumerate yourself from 0 to 3 since you have 4 tiles in total.
From both your questions it seems that you lack some basic programming knowledge of algorithms/approaches to problems. You should try to fill that gap, which will make you progress MUCH MUCH faster in your programming endeavors!

Android: why is native code so much faster than Java code

In the following SO question: https://stackoverflow.com/questions/2067955/fast-bitmap-blur-for-android-sdk #zeh claims a port of a java blur algorithm to C runs 40 times faster.
Given that the bulk of the code includes only calculations, and all allocations are only done "one time" before the actual algorithm number crunching - can anyone explain why this code runs 40 times faster? Shouldn't the Dalvik JIT translate the bytecode and dramatically reduce the gap to native compiled code speed?
Note: I have not confirmed the x40 performance gain myself for this algorithm, but all serious image manipulation algorithm I encounter for Android, are using the NDK - so this supports the notion that NDK code will run much faster.
For algorithms that operate over arrays of data, there are two things that significantly change performance between a language like Java, and C:
Array bound checking: Java will check every access, bmap[i], and confirm i is within the array bounds. If the code tries to access out of bounds, you will get a useful exception. C & C++ do not check anything and just trust your code. The best case response to an out of bounds access is a page fault. A more likely result is "unexpected behavior".
Pointers: You can significantly reduce the operations by using pointers.
Take this innocent example of a common filter (similar to blur, but 1D):
for(int i = 0; i < ndata - ncoef; ++i) {
z[i] = 0;
for(int k = 0; k < ncoef; ++k) {
z[i] += c[k] * d[i + k];
}
}
When you access an array element, coef[k] is:
Load address of array coef into register;
Load value k into a register;
Sum them;
Go get memory at that address.
Every one of those array accesses can be improved because you know that the indexes are sequential. Neither the compiler, nor the JIT can know that the indexes are sequential so they cannot optimize fully (although they keep trying).
In C++, you would write code more like this:
int d[10000];
int z[10000];
int coef[10];
int* zptr;
int* dptr;
int* cptr;
dptr = &(d[0]); // Just being overly explicit here, more likely you would dptr = d;
zptr = &(z[0]); // or zptr = z;
for(int i = 0; i < (ndata - ncoef); ++i) {
*zptr = 0;
*cptr = coef;
*dptr = d + i;
for(int k = 0; k < ncoef; ++k) {
*zptr += *cptr * *dptr;
cptr++;
dptr++;
}
zptr++;
}
When you first do something like this (and succeed in getting it correct) you will be surprised how much faster it can be. All the array address calculations of fetching the index and summing the index and base address are replaced with an increment instruction.
For 2D array operations such as blur on an image, an innocent code data[r,c] involves two value fetches, a multiply and a sum. So with 2D arrays the benefits of pointers allows you to remove multiply operations.
So the language allows real reduction in the operations the CPU must perform. The cost is that the C++ code is horrendous to read and debug. Errors in pointers and buffer overflows are food for hackers. But when it comes to raw number grinding algorithms, the speed improvement is too tempting to ignore.
Another factor not mentioned above is the garbage collector. The problem is that garbage collection takes time, plus it can run at any time. This means that a Java program which creates lots of temporary objects (note that some types of String operations can be bad for this) will often trigger the garbage collector, which in turn will slow down the program (app).
Following is an list of Programming Language based on the levels,
Assembly Language ( Machine Language, Lover Level )
C Language ( Middle Level )
C++, Java, .net, ( Higher Level )
Here Lower level language has direct access to the Hardware. As long as the level gets increased the access to the hardware gets decrease. So Assembly Language's code runs at the highest speed while other language's code runs based on their levels.
This is the reason that C Language's code run much faster than the Java's code.

Android - Determine tile bitmap based on surrounding tiles

I have been working on a tile-based terrain generation system , and have run into a bit of a snag. I am hoping to create a series of transition tiles that will mark the transition between water and land, and am having trouble figuring out an efficient way to figure out which tile should be which.
My first attempt (illustrated below) would basically run each tile through a series of if statements to figure out which one it should be. The main problem with this is that, with a 100 tile x 100 tile world map, it would be running though 10,000 iterations, accessing the data on the 8 surrounding tiles (80,000 operations), and then running through up to four if statements (320,000 operations). It just seems to me that this would be horribly inefficient and slow.
The upside of this method is that it would only run on land tiles, and would first check to make sure that it is adjacent to at least one water tile, which would greatly reduce the number of required operations.
Here's the basic chart I drew up that walks through the surrounding tiles and picks out the appropriate tile.
My second idea was to essentially start walking through tiles and, once I hit a coastal tile, follow the coast in both directions, assigning tiles as I went. this method would make sure that the tile hasn't already been figured out before starting. The problem with this is that, one, I can't figure out quite how that would work, and two, as a result I have no idea how efficient it would be.
A friend told me about a third method that might work. It takes water tiles and sets them equal to 0 and land tiles, which are set to 1. Then, it takes the surrounding tiles and numbers them from 1 to 9. From there were walk through them and create a string on 0's and 1's:
W W W
W L L
L L L
would be: 000011111
0*2^0 + 0*2^1 + 0*2^2 + 0*2^3 + 1*2^4 + 1*2^5 + 1*2^6 + 1*2^7 + 1*2^8
0*1 + 0*2 + 0*4 + 0*8 + 1*16 + 1*32 + 1*64 + 1*128 + 1*126 = 496
The theory is that I would assign the tile associated with that combination the number 496 and load it in response. The problem is that each edge has 13 or 14 combinations taht would result in its use. for instance:
W W L L W W
W L L and W L L Both need the same tile as the above example, but
L L L L L L produce different numbers.
Essentially, to make this method work I would have to figure out the final number for each possible combination of water and land that would result in a particular tile, and then run the final number through a series of ifs / cases to pick out the appropriate bitmap. This would be just as, or more, inefficient than the if blocks.
So, coming to the actual question in all of this. Does anyone know of an alternate way of doing this, or a way to make either of these methods more efficient?
I actually just wrote this part of a game I started working on. Took me a little while to think of the solution but when I did I couldn't believe I didn't think of it earlier. If you think about it, each tile has 8 possible "connections":
1 2 3
4 x 5
6 7 8
And each connection can either contain a tile it connects to or not. So this is sweet, it means its a very binary system and we can represent every combination with 8 bits (or 1 byte), and we know every combination is represented sequentially from 0-255, so we can easily use a lookup table (well, lookup array) to find the correct image. Though this does mean there are 256 possible combinations of connection (not 256 different images mind you, like you said above different combinations will use the same tile graphic) we have to generate. What I did (and I recommend), is wrote a small script to generate the lookup array.
Now the way to maintain this is that every tile has an 8 length array of the tiles it is connected to. When loading the map, fill in the "connections" array of the tiles as you go. Once a tile has all its connections (or once all tiles are loaded) then calculate the "connection mask" or "connection value" for each tile (which is the index into the lookup array). This is done by looping through the "connections" array and building the mask using bit shifts. After that you should only ever need to do very minimal processing again, and only on the individual tiles that are added/removed/changed and the 8 possible tiles its connected to.
Hope this helps. If you need more details or example code I can provide that later!

Categories

Resources