Java OpenCV cant copy from MatOfInt4 into MatOfInt4 - java

I have an OpenCV 4.2.0 application using HoughLinesP to detect lines in an image that's working fine with C++ and Objective-C. Now I need to have the same functionality working for java on Android.  
I've been fighting with it for a couple of days now and boiled it down to the following issue.  I can't copy a value from one MatOfInt4 to another MatOfInt4 using a for loop with lines2.put(i,0, lines.get(i, 0));
Below is the piece of code and the log outputs.  There are no compiler errors or runtime errors, just no values saved in the lines2 destination MatOfInt4. Either I have misunderstood how the put method works or there is something else wrong.
Does anyone know where this could be going wrong?  Any experts with Java and OpenCV able to give any guidance or corrections to the code below so that it will work?
You can see lines has 180 entries, the for loop counts 180 loops but lines2 is empty when it's finished.  I can get() the values correctly from lines and I'm using the values in other parts of the code, but I can't put() anything into lines2.
MatOfInt4 lines = new MatOfInt4();
lines = houghLinesP(sub);
Log.i(TAG, "Total Sub Lines Returned: " + lines.size());
MatOfInt4 lines2 = new MatOfInt4();
for(int i = 0; i < lines.rows(); i++) {
lines2.put(i,0, lines.get(i, 0));
Log.i(TAG, "Count of loop: " + i);
}
Log.i(TAG, "Dump of lines2 Returned: " + lines2.dump());
Log.i(TAG, "Total Lines2 Returned: " + lines2.size());
Results of test code:
Total Sub Lines Returned: 1x180
Dump of lines2 Returned: []
Count of loop: 180
Total Lines2 Returned: 0x0
Any help or guidance would be greatly appreciated.

The lines2 matrix has no size, so you cannot set values in it. To solve the problem you can allocate the matrix with the appropriate size, e.g.
MatOfInt4 lines2 = new MatOfInt4();
lines2.create(1,lines.rows(), lines.type());
// alternatively:
Mat lines2 = new Mat(1,lines.rows(), lines.type());
If you don't do anything else in the loop you could also just transpose the matrix to achieve the same result:
Mat lines2 = lines.t();
This transposed matrix will already contain the correct values. For my example image this produces the following output:
Total Sub Lines Returned: 1x295
Dump of lines2 Returned: [9, 187, 137, 201, 353, 211, 430, 213, 95, etc...
Total Lines2 Returned: 295x1

Related

Java GRIB-Decoder: Extract data from GRIB2 files

I've downloaded some grib data files from here: ftp://data-portal.ecmwf.int/20160721000000/ (file type is .bin) and want to extract the data from this file in my Java application (I want to load the extracted data into a database later). I'm just trying with the file ftp://wmo:essential#data-portal.ecmwf.int/20160721000000/A_HWXE85ECEM210000_C_ECMF_20160721000000_24h_em_ws_850hPa_global_0p5deg_grib2.bin.
Therefore I've created a new Java project and added the two libraries grib-8.0.29.jar and netcdfAll-4.6.6.jar. Documentation for the grib API can be found here: http://www.unidata.ucar.edu/software/decoders/grib/javadoc/. I need to open the downloaded files to get the data. Retrieving some metadata via Grib2Dump seems to work (see below). Also the Grib2Input instance sais, that I have a valid GRIB file of version 2.
Here my working code for retrieving some metadata:
public static void main(String[] args) throws IOException, InterruptedException {
File srcDir = new File("C://test//");
File[] localFiles = srcDir.listFiles();
for (File tempFile : localFiles) {
RandomAccessFile raf = new RandomAccessFile(tempFile.getAbsolutePath(), "r");
System.out.println("======= Grib2GDSVariables ==========");
Grib2GDSVariables gdsVariables = new Grib2GDSVariables(raf.readBytes(raf.read()));
System.out.println("Gds key : " + gdsVariables.getGdsKey());
System.out.println("======= Grib2Input ==========");
Grib2Input input = new Grib2Input(raf);
System.out.println(Grib2Input.isValidFile(raf));
System.out.println("scan : " + input.scan(true, true));
System.out.println("getGDSs.size: " + input.getGDSs().size());
System.out.println("getProducts.size: " + input.getProducts().size());
System.out.println("getRecords.size: " + input.getRecords().size());
System.out.println("edition: " + input.getEdition());
System.out.println("======= Grib2Dump ==========");
Grib2Dump dump = new Grib2Dump();
dump.gribDump(new String[] {tempFile.getAbsolutePath()});
System.out.println("======= Grib2ExtractRawData ==========");
Grib2ExtractRawData extractRawData = new
Grib2ExtractRawData(raf); extractRawData.main(new String[] {tempFile.getAbsolutePath()});
}
System.out.println("finished");
}
This produces the following output:
======= Grib2GDSVariables ==========
Gds key : -1732955898
======= Grib2Input ==========
true
scan : true
getGDSs.size: 0
getProducts.size: 0
getRecords.size: 0
edition: 2
======= Grib2Dump ==========
--------------------------------------------------------------------
Header : GRIB2
Discipline : 0 Meteorological products
GRIB Edition : 2
GRIB length : 113296
Originating Center : 98 European Center for Medium-Range Weather Forecasts (RSMC)
Originating Sub-Center : 0
Significance of Reference Time : 1 Start of forecast
Reference Time : 2016-07-21T00:00:00Z
Product Status : 0 Operational products
Product Type : 1 Forecast products
Number of data points : 259920
Grid Name : 0 Latitude_Longitude
Grid Shape: 6 Earth spherical with radius of 6,371,229.0 m
Number of points along parallel: 720
Number of points along meridian: 361
Basic angle : 0
Subdivisions of basic angle: -9999
Latitude of first grid point : 90.0
Longitude of first grid point : 0.0
Resolution & Component flags : 48
Winds : True
Latitude of last grid point : -90.0
Longitude of last grid point : 359.5
i direction increment : 0.5
j direction increment : 0.5
Grid Units : degrees
Scanning mode : 0
Product Definition : 2 Derived forecast on all ensemble members at a point in time
Parameter Category : 2 Momentum
Parameter Name : 1 Wind_speed
Parameter Units : m s-1
Generating Process Type : 4 Ensemble Forecast
ForecastTime : 24
First Surface Type : 100 Isobaric surface
First Surface value : 85000.0
Second Surface Type : 255 Missing
Second Surface value : -9.999E-252
======= Grib2ExtractRawData ==========
finished
I tried around for two days now but couldn't get it to work! I can't obtain the content data (lat, lon, value) from the file...
Can someone give an example in Java?
You shouldn't use the GRIB classes in netCDF-java directly. Instead, use
NetcdfFile.open()
That will give you access through the CDM, giving you a straightforward interface with variables and attributes. There's a tutorial here: https://www.unidata.ucar.edu/software/thredds/current/netcdf-java/tutorial/NetcdfFile.html

OpenCV 3.0 svm always predicts 0 (java)

I'm new to opencv's svm's. I tried a sample classifier but it only returns 0 as the predicted label. I even used the value 5 for training as well as the prediction.
I've been changing the values for about a hundred times but i just don't get what's wrong. I'm using OpenCV 3.0 with Java. Here's my code:
Mat labels = new Mat(new Size(1,4),CvType.CV_32SC1);
labels.put(0, 0, 1);
labels.put(1, 0, 1);
labels.put(2, 0, 1);
labels.put(3, 0, 0);
Mat data = new Mat(new Size(1,4),CvType.CV_32FC1);
data.put(0, 0, 5);
data.put(1, 0, 2);
data.put(2, 0, 3);
data.put(3, 0, 8);
Mat testSamples = new Mat(new Size(1,1),CvType.CV_32FC1);
testSamples.put(0,0,5);
SVM svm = SVM.create();
TermCriteria criteria = new TermCriteria(TermCriteria.EPS + TermCriteria.MAX_ITER,100,0.1);
svm.setKernel(SVM.LINEAR);
svm.setType(SVM.C_SVC);
svm.setGamma(0.5);
svm.setNu(0.5);
svm.setC(1);
svm.setTermCriteria(criteria);
//data is N x 64 trained data Mat , labels is N x 1 label Mat with integer values;
svm.train(data, Ml.ROW_SAMPLE, labels);
Mat results = new Mat();
int predictedClass = (int) svm.predict(testSamples, results, 0);
Even if i change the lables to 1 and 2, I still get 0.0 as a response. So something has to be absolutely wrong... I just don't know what to do. Please help! :)
I had a similar problem in C++. I'm not too sure if it's the same in Java but in C++ the predictions were saved in the results Matrix instead of returned as a float.

How to find the local maxima and minima in an image

I am learning how to get the local and global maximum in an image, and as far as know, in one image there is only one global Maximum and one global minimum, and i managed to get these values and their corresponding locations in the image. so my questions are:
how to get the local maxima in an image
how to get the local minima in an image
as you see in the code below, I am using mask, but at run time i receieve the below mentioned error message. so please let me know why do we need mask and how to use it properly.
update:
Line 32 is: MinMaxLocResult s = Core.minMaxLoc(gsMat, mask);
code:
public static void main(String[] args) {
MatFactory matFactory = new MatFactory();
FilePathUtils.addInputPath(path_Obj);
Mat bgrMat = matFactory.newMat(FilePathUtils.getInputFileFullPathList().get(0));
Mat gsMat = SysUtils.rgbToGrayScaleMat(bgrMat);
Log.D(TAG, "main", "gsMat.dump(): \n" + gsMat.dump());
Mat mask = new Mat(new Size(3,3), CvType.CV_8U);//which type i should set for the mask
MinMaxLocResult s = Core.minMaxLoc(gsMat, mask);
Log.D(TAG, "main", "s.maxVal: " + s.maxVal);//to get the global maximum
Log.D(TAG, "main", "s.minVal: " + s.minVal);//to get the global minimum
Log.D(TAG, "main", "s.maxLoc: " + s.maxLoc);//to get the coordinates of the global maximum
Log.D(TAG, "main", "s.minLoc: " + s.minLoc);//to get the coordinates of the global minimum
}
error message:
OpenCV Error: Assertion failed (A.size == arrays[i0]->size) in cv::NAryMatIterator::init, file ..\..\..\..\opencv\modules\core\src\matrix.cpp, line 3197
Exception in thread "main" CvException [org.opencv.core.CvException: ..\..\..\..\opencv\modules\core\src\matrix.cpp:3197: error: (-215) A.size == arrays[i0]->size in function cv::NAryMatIterator::init
]
at org.opencv.core.Core.n_minMaxLocManual(Native Method)
at org.opencv.core.Core.minMaxLoc(Core.java:7919)
at com.example.globallocalmaxima_00.MainClass.main(MainClass.java:32)
In order to calculate global min/max values you don't need to use mask completely.
For calculating local min/max values you can do a little trick. You need to perform dilate/erode operation and then compare pixel value with values of original image. If value of original image and dilated/eroded image are equal therefore this pixel is local min/max.
The code is following:
Mat eroded = new Mat();
Mat dilated = new Mat();
Imgproc.erode(gsMat, eroded, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5,5)));
Imgproc.dilate(gsMat, dilate, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5,5)));
Mat localMin = new Mat(gsMat.size(), CvType.CV_8U, new Scalar(0));
Mat localMax = new Mat(gsMat.size(), CvType.CV_8U, new Scalar(0));
for (int i=0; i<gsMat.height; i++)
for (int j=0; j<gsMat.width; j++)
{
if (gsMat.get(i,j) == eroded.get(i,j))
localMin.put(i,j,255);
if (gsMat.get(i,j) == dilated.get(i,j))
localMax.put(i,j,255);
}
Please note, I'm not a Java programmer. So, code is only illustration of algorithm.

R, Java, RCaller

So i'm trying to use RCaller to do the following (in psuedo-code):
x=simarray(..) // in java
'send x to R'
run y = rlogcon(40000, sort(x)) //in R, rlogcon is part of rlogcondens and the function
produces a numeric vector of length 40000
//send y to java and hold it in a double matrix.
this is what i've got in my main function (i've adapted one of the examples I found, but I must have made a mistake/misunderstood something. I tested the example on my machine, and it worked as expected):
RCaller caller = new RCaller();
RCode code = new RCode();
double[] x = a.simarraysimbeta(5, 1, 100, 30, 40); //some method
savesample("simarraysimbeta.txt",x); //testing, it works.
caller.setRscriptExecutable("C:\\Program Files\\R\\R-3.1.0\\bin\\Rscript.exe");
code.addDoubleArray("X", x);
code.addRCode("library(logcondens)"); //rlogcon is part of logcondens library
code.addRCode("ols <- rlogcon(40,000, sort(X))");
caller.setRCode(code);
caller.runAndReturnResult("ols");
double[] residuals = caller.getParser().getAsDoubleArray("X_star");
and the following relevent imports:
import rcaller.RCaller;
import rcaller.RCode;
import rcaller;
I get the following error:
Exception in thread "main" rcaller.exception.ParseException: Can not
handle R results due to : rcaller.exception.ParseException: Can not
parse output: The generated file
C:\Users\jo\AppData\Local\Temp\Routput8804446513483695061 is empty
here is the output:
concat<-function(to,...){
to<-paste(to,toString(...),sep="");
return(to);
}
cleanNames<-function(names){
cleanNames<-paste(unlist(strsplit(names,"\\.")),collapse="_");
Exception in thread "main" rcaller.exception.ParseException: Can not
handle R results due to : rcaller.exception.ParseException: Can not
parse output: The generated file
C:\Users\jo\AppData\Local\Temp\Routput8804446513483695061 is empty
cleanNames<-paste(unlist(strsplit(cleanNames,"<")),collapse="");
at rcaller.RCaller.runAndReturnResult(RCaller.java:409)
cleanNames<-paste(unlist(strsplit(cleanNames,">")),collapse="");
at dissertation.Dissertation.main(Dissertation.java:709)
cleanNames<-paste(unlist(strsplit(cleanNames," ")),collapse="");
cleanNames<-paste(unlist(strsplit(cleanNames,"\\(")),collapse="");
cleanNames<-paste(unlist(strsplit(cleanNames,"\\)")),collapse="");
cleanNames<-paste(unlist(strsplit(cleanNames,"\\[")),collapse="");
cleanNames<-paste(unlist(strsplit(cleanNames,"\\]")),collapse="");
cleanNames<-paste(unlist(strsplit(cleanNames,"\\*")),collapse="");
return(cleanNames);
}
makevectorxml<-function(code,objt,name=""){
xmlcode<-code;
if(name==""){
varname<-cleanNames(deparse(substitute(obj)));
}else{
varname<-name;
}
obj<-objt;
n <- 0; m <- 0
mydim <- dim(obj)
if(!is.null(mydim)){
n <- mydim[1]; m <- mydim[2];
}else{
n <- length(obj); m <- 1;
}
if(is.matrix(obj)) obj<-as.vector(obj);
if(typeof(obj)=="language") obj<-toString(obj);
if(typeof(obj)=="logical") obj<-as.character(obj);
if(is.vector(obj) && is.numeric(obj)){
xmlcode<-paste(xmlcode,"<variable name=\"",varname,"\" type=\"numeric\" n=\"", n, "\" m=\"", m, "\">",sep="");
for (i in obj){
xmlcode<-paste(xmlcode,"<v>",sep="");
xmlcode<-paste(xmlcode,toString(i),sep="");
xmlcode<-paste(xmlcode,"</v>",sep="");
}
xmlcode<-paste(xmlcode,"</variable>\n",sep="");
}
if(is.vector(obj) && is.character(obj)){
xmlcode<-paste(xmlcode,"<variable name=\"",varname,"\" type=\"character\">\n",sep="");
for (i in obj){
xmlcode<-paste(xmlcode,"<v>",sep="");
xmlcode<-paste(xmlcode,toString(i),sep="");
xmlcode<-paste(xmlcode,"</v>",sep="");
}
xmlcode<-paste(xmlcode,"</variable>\n");
}
return(xmlcode);
}
makexml<-function(obj,name=""){
xmlcode<-"<?xml version=\"1.0\"?>\n";
xmlcode<-concat(xmlcode,"<root>\n");
if(!is.list(obj)){
xmlcode<-makevectorxml(xmlcode,obj,name);
}
else{
objnames<-names(obj);
for (i in 1:length(obj)){
xmlcode<-makevectorxml(xmlcode,obj[[i]],cleanNames(objnames[[i]]));
}
}
xmlcode<-concat(xmlcode,"</root>\n");
return(xmlcode);
}
X<-c(##100 doubles);
library(logcondens)
ols <- rlogcon(40,000, sort(X))
cat(makexml(obj=ols, name="ols"), file="C:/Users/##/AppData/Local/Temp/Routput8804446513483695061")
40,000 shold be 40000 in your code.
There are two ways in which a file remains empty:
there is an error in R code
the result is NULL or NA
I recommend you to use tryCach in R
ols <- tryCatch({
rlogcon(40,000, sort(X))
}, error = function(e) {
-1
})
And at the end if ols equlas -1, you'll know that there was an error in R

Autoit Java argument in run command through $chosen variable

I made a combo:
$Combo1 = GUICtrlCreateCombo("Java Memory", 24, 872, 145, 25, $CBS_DROPDOWNLIST)
GUICtrlSetData(-1, "-Xmx1024M|-Xmx2048M|-Xmx3072M|-Xmx4096M")
Then I added something to read it:
$chosen = GUICtrlRead($Combo1)
Then I made a run command and put $chosen in it:
Run ("java -jar spigot-1.6.2-R0.1.jar " & $chosen, "E:\Spill\Alle spill\Minecraft\KnarCraft 2013")
When I don't choose an option in the drop down list, it starts. When I do, it comes a window that disappears instantly, but it shows all valid parameters so therefore something is wrong in the way it reads it. I think it has something to do with the - but I don't know how i should do it. I tried using a - and then the variable, but then it reads it as -$chosen instead of "-" + "choice in $chosen".
First off, the order of your java command line I believe is important, and so the -Xmx option should come after the "java" and before the "-jar" tokens.
Next, I wonder if you're trying to use too much memory. Have you considered testing this with smaller values?
For example:
$Combo1 = GUICtrlCreateCombo("Java Memory", 10, 10, 142, 25, $CBS_DROPDOWNLIST)
GUICtrlSetData(-1, "-Xmx100M|-Xmx200M|-Xmx400M|-Xmx800M|-Xmx1024M|-Xmx2048M|-Xmx3072M|-Xmx4096M")
Then see if any of the smaller numbers work and if the larger numbers break the program.
My test program:
AutoIt program, MyFoo.au3:
#include <ComboConstants.au3>
#include <GUIConstantsEx.au3>
Example()
Func Example()
Local $msg
GUICreate("My GUI combo") ; will create a dialog box that when displayed is centered
$Combo1 = GUICtrlCreateCombo("Java Memory", 10, 10, 142, 25, $CBS_DROPDOWNLIST)
GUICtrlSetData(-1, "-Xmx100M|-Xmx200M|-Xmx400M|-Xmx800M|-Xmx1024M|-Xmx2048M|-Xmx3072M|-Xmx4096M")
GUISetState()
; Run the GUI until the dialog is closed
While 1
$msg = GUIGetMsg()
If $msg = $Combo1 Then
$chosen = GUICtrlRead($Combo1)
$runString1 = "java " & $chosen & " -jar MyFoo.jar"
$runString2 = "java -jar MyFoo.jar " & $chosen
ConsoleWrite($runString1 & #CRLF)
Run($runString1)
EndIf
If $msg = $GUI_EVENT_CLOSE Then ExitLoop
WEnd
EndFunc
Java test program, MyAutoItFoo.java. Of course this was jar'd first:
import javax.swing.JOptionPane;
public class MyAutoItFoo {
public static void main(String[] args) {
long heapSize = Runtime.getRuntime().totalMemory();
long heapMaxSize = Runtime.getRuntime().maxMemory();
String heapString = String.format("Heap Size = %H; Max Heap = %H",
heapSize, heapMaxSize);
System.out.println(heapString);
JOptionPane.showMessageDialog(null, heapString);
}
}

Categories

Resources