Draw points correctly with Canvas - java

I have a python script that draws landmarks on the contours of eye region with image input got from ckpts files (model) using OpenCV.
I want to draw those points ( landmarks ) in the same picture.
I got predictions points from the picture and I tried to draw those points (x,y) using Canvas but the results are different.
Difference between the two images:
Landmarks are drawn using python script (OpenCV)
Landmarks are draw using java code (Canvas)
I have tried many ways and I use Canvas library to draw points on imageview ( I loaded the same image in assets folder ) but this doesn't solve my problem..
This is a python code that shows how to draw landmarks on image:
predictions = estimator.predict(input_fn=_predict_input_fn)
for _, result in enumerate(predictions):
img = cv2.imread(result['name'].decode('ASCII') + '.jpg')
print(result['logits'])
print(result['name'])
marks = np.reshape(result['logits'], (-1, 2)) * IMG_WIDTH
print("reshape values "+str(np.reshape(result['logits'], (-1,2))))
print("marks "+str(marks))
for mark in marks:
cv2.circle(img, (int(mark[0]), int(
mark[1])), 1, (0, 255, 0), -1, cv2.LINE_AA)
try:
img = cv2.resize(img, (512, 512))
cv2.imshow('result', img)
except Exception as e:
print(str(e))
# output_node_names = [n.name for n in tf.get_default_graph().as_graph_def().node]
# print(output_node_names)
cv2.waitKey()
This file shows print logs from python code:
[0.33135968 0.19592011 0.34212315 0.17297666 0.36624995 0.16413747
0.3894139 0.17440952 0.39828074 0.1978043 0.3891497 0.22268474
0.36345637 0.22974193 0.3401759 0.2193309 0.30167252 0.20411113
0.3167112 0.19134495 0.33793524 0.18388326 0.3642417 0.18049955
0.3903508 0.18533507 0.40906873 0.1957745 0.42142123 0.21091096
0.40550107 0.21829814 0.38345626 0.22071144 0.35900232 0.22142673
0.3363348 0.21877256 0.3161971 0.2133534 0.62843406 0.21482795
0.6389724 0.1914106 0.6628249 0.1835615 0.6858679 0.19583184
0.6946868 0.22111627 0.6840309 0.24444285 0.66027373 0.25241333
0.6351568 0.24192403 0.60499936 0.22642238 0.6210091 0.21289764
0.6423563 0.2042976 0.6685919 0.20277795 0.69201195 0.20948553
0.70882106 0.22015369 0.71931773 0.23518339 0.7076659 0.24166131
0.69054717 0.24350837 0.6694564 0.24258481 0.64537776 0.23927754
0.62199306 0.23511863]
b'C:\\Users\\*******\\cnn-facial-landmark\\targetiris\\irisdata-300VW_Dataset_2015_12_14-017-000880'
reshape values [[0.33135968 0.19592011]
[0.34212315 0.17297666]
[0.36624995 0.16413747]
[0.3894139 0.17440952]
[0.39828074 0.1978043 ]
[0.3891497 0.22268474]
[0.36345637 0.22974193]
[0.3401759 0.2193309 ]
[0.30167252 0.20411113]
[0.3167112 0.19134495]
[0.33793524 0.18388326]
[0.3642417 0.18049955]
[0.3903508 0.18533507]
[0.40906873 0.1957745 ]
[0.42142123 0.21091096]
[0.40550107 0.21829814]
[0.38345626 0.22071144]
[0.35900232 0.22142673]
[0.3363348 0.21877256]
[0.3161971 0.2133534 ]
[0.62843406 0.21482795]
[0.6389724 0.1914106 ]
[0.6628249 0.1835615 ]
[0.6858679 0.19583184]
[0.6946868 0.22111627]
[0.6840309 0.24444285]
[0.66027373 0.25241333]
[0.6351568 0.24192403]
[0.60499936 0.22642238]
[0.6210091 0.21289764]
[0.6423563 0.2042976 ]
[0.6685919 0.20277795]
[0.69201195 0.20948553]
[0.70882106 0.22015369]
[0.71931773 0.23518339]
[0.7076659 0.24166131]
[0.69054717 0.24350837]
[0.6694564 0.24258481]
[0.64537776 0.23927754]
[0.62199306 0.23511863]]
marks [[37.112286 21.943052]
[38.317795 19.373386]
[41.019993 18.383396]
[43.614357 19.533867]
[44.607445 22.154081]
[43.584766 24.940691]
[40.707115 25.731096]
[38.0997 24.565062]
[33.787323 22.860447]
[35.471653 21.430634]
[37.848747 20.594925]
[40.79507 20.21595 ]
[43.719288 20.757528]
[45.815697 21.926743]
[47.199177 23.622028]
[45.41612 24.44939 ]
[42.9471 24.71968 ]
[40.20826 24.799793]
[37.6695 24.502527]
[35.414074 23.89558 ]
[70.38461 24.06073 ]
[71.56491 21.437988]
[74.23639 20.558887]
[76.81721 21.933167]
[77.80492 24.765022]
[76.61146 27.3776 ]
[73.95066 28.270294]
[71.137566 27.095491]
[67.759926 25.359306]
[69.553024 23.844536]
[71.9439 22.881332]
[74.88229 22.71113 ]
[77.50534 23.46238 ]
[79.387955 24.657213]
[80.56358 26.34054 ]
[79.25858 27.066067]
[77.341286 27.272938]
[74.97912 27.169498]
[72.28231 26.799084]
[69.66322 26.333286]]
Java code (Android)
private void drawpoint(ImageView imageView,float x,float y, int raduis){
myOptions.inDither = true;
myOptions.inScaled = false;
myOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;// important
myOptions.inPurgeable = true;
canvas.drawCircle(x,y, raduis, paint);
imageView = (ImageView)findViewById(R.id.imageView);
imageView.setAdjustViewBounds(true);
imageView.setImageBitmap(mutableBitmap);
}
drawpoint(image2, 38, 19,1);
drawpoint(image2,41,18,1);
drawpoint(image2,43,19,1);
drawpoint(image2,40,25,1);
drawpoint(image2,38,24,1);
How can I solve this problem?

Problem solved.
I used the OpenCV library for drawing in Android instead of Canvas library.
I have used exactly this function:
Imgproc.circle()

Related

OPENCV crash when saving to file trained machine learning data (like SVM or ANN)

I have built a simple project in android studio, and included OpenCV in order to train either an SVM (support vector machine) or an ANN (artificial neural network). Everything seems to go well, including data creation, training and inspection of trained data, except for saving. Whenever I save a opencv ml-object (like ann.save(...) or svm.save(...)), android studio crashes.
SVM -
When I extract supportvectors using the line
classifier.getSupportVectors()
the numbers seem sain. However, the app crashes when I move past a breakpoint placed at
classifier.save("C:\\foo\\trentsvm.txt");
In logCat I dig up the following feedback:
07-04 14:36:10.939 25258-25258/com.example.tbrandsa.opencvtest A/libc:
Fatal signal 11 (SIGSEGV), code 2, fault addr 0x7f755f53f0 in tid
25258 (ndsa.opencvtest) [ 07-04 14:36:10.942 439: 439 W/]
debuggerd: handling request: pid=25258 uid=10227 gid=10227 tid=25258
I get a similar error if i instead try to save an artificial neural network (ANN), see update far below.
I have tried saving the file as XML and txt, and as "C:\trentsvm.someformat", and as "trentsvm.someformat". I also get the same error in my Eclipse java project. High pain, no gain. Full code is below. Could you help?
PS: I use OpenCv version 3.2.0. and Android Studio 2.3.2
// I based this code on stuff i found online. Not sure if all is as important or good.
// Purpose: multilabel classification - digit recognition for android app.
// Create data and labels for a digit recognition algorithm
int numTargets = 10; // (0-9 => 10 types of labels)
int totalSamples = 100; // Could have been number of images of digits
int totalIndicators = 10; // Could have been number of properites per digit image.
Mat labels = new Mat(totalSamples,1, CvType.CV_16S);
Mat data = new Mat(totalSamples, totalIndicators,CvType.CV_16S);
// Fill with dummy values:
for (int s = 0; s<totalSamples; s++)
{
int someLabel = s%numTargets;
labels.put(s,0, (double)someLabel);
for (int m = 0; m<totalIndicators; m++)
{
int someDataValue = (s%numTargets)*totalIndicators + m;
data.put(s, m, (double)someDataValue);
}
}
data.convertTo(data, CvType.CV_32F);
labels.convertTo(labels, CvType.CV_32S);
SVM classifier = SVM.create();
TermCriteria criteria = new TermCriteria(TermCriteria.EPS + TermCriteria.MAX_ITER,100,0.1);
classifier.setKernel(SVM.LINEAR);
classifier.setType(SVM.C_SVC); //We choose here the type CvSVM::C_SVC that can be used for n-class classification (n >= 2).
classifier.setGamma(0.5);
classifier.setNu(0.5);
classifier.setC(1);
classifier.setTermCriteria(criteria);
classifier.train(data, Ml.ROW_SAMPLE, labels);
// Check how trained SVM predicts the training data
Mat estimates = new Mat(totalSamples, 1, CvType.CV_32F);
classifier.predict(data, estimates, StatModel.RAW_OUTPUT);
for (int i = 0; i<totalSamples; i++)
{
double l = labels.get(i, 0)[0];
double e = estimates.get(i, 0)[0];
System.out.print("\n fact: "+l+", estimat: "+e);
}
Mat suppV = classifier.getSupportVectors();
try {
if (classifier.isTrained()){
// It crashes at the next line!
classifier.save("C:\\foo\\trentsvm.txt");
}
}
catch (Exception e)
{
}
Update july 5th: As suggested by ZdaR, I tried the to use an in-phone adress, but it did not solve the problem.
String address = Environment.getExternalStorageDirectory().getPath()+"/trentsvm.xml";
// address now has value "storage/emulated/0/trentsvm.xml"
classifier.save(address);
In logcat:
07-05 14:50:12.420 11743-11743/com.example.tbrandsa.opencv2 A/libc:
Fatal signal 11 (SIGSEGV), code 2, fault addr 0x7d517f1990 in tid
11743 (brandsa.opencv2)
[ 07-05 14:50:12.424 3134: 3134 W/ ] debuggerd: handling
request: pid=11743 uid=10319 gid=10319 tid=11743
Update july 6th:
When I run the same script in eclipse and use a debugger (JUnit 4, VM arguments: -Djava.library.path=C:\Users\tbrandsa\Downloads\opencv\build\java\x64;src\test\jniLibs, ) debugging on the pc without device, the caught exception "e" says the following
cause= Exception,
detailMessage= "Unknown Exception" ,
stackTrace=> StackTraceElement[0] ,
suppressedExeptions= Collections$UnmodifiableRandomAccessList,
Update july 13th:
I just tried with an artificial neural network (ANN) too, and it crashes when trying to save.
Error:
Fatal signal 11 (SIGSEGV), code 1, fault addr 0x15a57e688000c in tid
8507 (brandsa.opencv2) debuggerd: handling request: pid=8507
uid=10319 gid=10319 tid=8507
Code:
// Mat data is of size 100*20*CV_32FC1,
// Mat labels is of size 100*1*CV_32FC1
// layerSizes is of size 3*1*CV_8UC1
int[] hiddenLayers = {10};
Mat layerSizes = new Mat(2 + hiddenLayers.length,1,CvType.CV_8U);
layerSizes.put(0, 0, data.width());
for (int l = 0; l< hiddenLayers.length; l++){
layerSizes.put(1 + l, 0,hiddenLayers[l]);}
layerSizes.put(1 + hiddenLayers.length, 0,labels.width());
ANN_MLP ann = ANN_MLP.create();
ann.setLayerSizes(layerSizes);
ann.setActivationFunction(ANN_MLP.SIGMOID_SYM);
ann.train(data, Ml.ROW_SAMPLE , labels);
ann.save("/storage/emulated/0/Pictures/no.rema.priceagent.test/trentann.xml");

glGetTexImage ACCESS VIOLATION

When I call glGetTexImage() on a texture from a Framebuffer, I get this error:
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffabf967a2b, pid=1816, tid=14712
Here is my code:
MagicaAdventura.GAME.gameBuffer.bindTexture();
glGetTexImage(GL_TEXTURE_2D, 0, GL12.GL_BGR, GL_UNSIGNED_BYTE, buf);//line that causes the error
And here is the code for the bind method:
public void bind(int texture) {
if(currentBound[texture] != resource.getID() || lastBoundInFramebuffer != Renderer.CURRENT_FRAMEBUFFER) {
GL13.glActiveTexture(GL13.GL_TEXTURE0 + texture);
lastBoundInFramebuffer = Renderer.CURRENT_FRAMEBUFFER;
currentBound[texture] = resource.getID();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, resource.getID());
}
}
The texture binding code works fine for other things.
The buffer wasn't allocating space for the padding the texture to a power of 2 so I switched to using glReadPixels.

Adding Two Mat of type 32FC4 in OpenCV for Android

To reduce the noise in an image, I am trying to get the average of 10 images.
Mat imgMain = new Mat(n_height, n_width, CvType.CV_32FC4);
Mat imgFin = new Mat(n_height, n_width, CvType.CV_32FC4);
for(int i=1; i <= 10; i++) {
//Crop the image
image.recycle();
image = null;
image = BitmapFactory.decodeFile("/storage/sdcard0/DCIM/A" + String.valueOf(i) + ".jpg");
pimage = Bitmap.createBitmap(image, leftOff1, topOff1, n_width, n_height);
Utils.bitmapToMat(pimage, imgMain);
scaleAdd(imgMain, 0.1, imgFin, imgFin);
}
Running the application, I get the following msg:
Caused by: CvException [org.opencv.core.CvException: cv::Exception:
/hdd2/buildbot/slaves/slave_ardbeg1/50-SDK/opencv/modules/core/src/matmul.cpp:2079:
error: (-215) src1.type() == src2.type() in function void
cv::scaleAdd(cv::InputArray, double, cv::InputArray, cv::OutputArray)
]
at org.opencv.core.Core.scaleAdd_0(Native Method)
at org.opencv.core.Core.scaleAdd(Core.java:6690)
at MainActivity.imageAnalysis(MainActivity.java:123)
where line 123 is scaleAdd(imgMaing, 0.1, imgFin, imgFin);
According to the reference, src1, src2 and dst MAT should be of same size and type. However, I get this error when I set imgFin type to 32FC4 but do not get any errors when imgFin is set to 8UC4. Any experience of this kind? I need to keep the floating numbers in imgFin which is why I can't go with 8UC4.
// this line will overwrite your imgMain,
// the type will be CV_8UC4, regardless, what you said before.
Utils.bitmapToMat(pimage, imgMain);
// so, convert to float:
imgMain.convertTo(imgMain, CvType.CV_32FC4);
// now add float images, to avoid precision loss:
scaleAdd(imgMain, 0.1, imgFin, imgFin);

RenderScript problems in eclipse

I'm trying to compile a sample of renderScript, but no way.
I have some errors that I can not solve:
[09.22.2014 18:28:44 - aaa] error: Error reading '... \ aaa \ process.rs'
Also I get that kind ScriptC_process there when I created the file .rs.
project.properties:
project.properties:
renderscript.target=18
renderscript.support.mode=true
sdk.buildtools=19.1.0
target=android-20
Also show the configuration of the project. Thank you very much.
EDIT:
The code of process.rs is as follows:
#pragma version(1)
#pragma rs java_package_name(com.example.aaa)
//multipliers to convert a RGB colors to black and white
const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};
void root(const uchar4 *v_in, uchar4 *v_out) {
//unpack a color to a float4
float4 f4 = rsUnpackColor8888(*v_in);
//take the dot product of the color and the multiplier
float3 mono = dot(f4.rgb, gMonoMult);
//repack the float to a color
*v_out = rsPackColorTo8888(mono);
}
I'm just using for example the following website:
[link] https://stuff.mit.edu/afs/sipb/project/android/docs/guide/topics/renderscript/compute.html

javacv: Iterating CvSeq in Java

I use:
cvFindContours(gray, mem, contours, Loader.sizeof(CvContour.class) , CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
and as the result I have CvSeq contours to iterate (as far as I understand it).
So I use it like that:
if(contours!=null) {
for (ptr = contours; ptr != null; ptr = ptr.h_next()) {
//..do sth with ptr
}
}
It works, but from time to time (quite often) I get:
Exception in thread "Thread-3" java.lang.NullPointerException: This pointer address is NULL.
at com.googlecode.javacv.cpp.opencv_core$CvSeq.h_next(Native Method)
at pl..filter(FullFilter.java:69)
at pl..Window$1.run(Window.java:41)
at java.lang.Thread.run(Unknown Source)
The line in which the exception is thrown is the line with ptr.h_next().
I tried to check for nulls but it doesn't work:
System.out.println("PTR="+ptr); // it's not null here!
if(ptr.h_next()==null) //exception in this line!
System.out.println("NULL");
System.out.println(ptr.h_next());
The first line shows:
PTR=com.googlecode.javacv.cpp.opencv_core$CvSeq[address=0x0,position=0,limit=1,capacity=1,deallocator=com.googlecode.javacpp.Pointer$NativeDeallocator#66d53ea4]
I tried also invoking contours.total() but it always throws the same exception.
So, what is a proper way to use in Java such C-like sequences?
EDIT:
my full method:
public IplImage filter(IplImage image) {
IplConvKernel kernel = cvCreateStructuringElementEx(2,2,1,1,CV_SHAPE_RECT, null);
cvDilate(image, image, kernel, 1);
kernel = cvCreateStructuringElementEx(5,5,2,2,CV_SHAPE_RECT, null);
cvErode(image, image, kernel, 1);
IplImage resultImage = cvCloneImage(image);
IplImage gray = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);
cvCvtColor(image, gray, CV_BGR2GRAY);
CvMemStorage mem = CvMemStorage.create();
CvSeq contours = new CvSeq();
CvSeq ptr = new CvSeq();
cvThreshold(gray, gray, 20, 255, opencv_imgproc.CV_THRESH_BINARY);
double thresh = 20;
Canny( gray, gray, thresh, thresh*2, 3 ,true);
cvFindContours(gray, mem, contours, Loader.sizeof(CvContour.class) , CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
int i=0;
CvRect boundbox;
if(contours!=null) {
for (ptr = contours; ptr != null; ptr = ptr.h_next()) { //EXCEPTION HERE!
System.out.println((i++)+"\t"+ptr);
cvDrawContours( resultImage, ptr, CvScalar.BLUE, CvScalar.RED, -1, 3, 8, cvPoint(0,0) );
System.out.println("PTR="+ptr);
}
}
return resultImage;
}
It works fine for some time and suddenly (probably when no contours found?) it ends with the following exception:
Exception in thread "Thread-3" java.lang.NullPointerException: This pointer address is NULL.
at com.googlecode.javacv.cpp.opencv_core$CvSeq.h_next(Native Method)
at pl.kasprowski.eyetracker.FullFilter2.filter(FullFilter2.java:39)
at pl.kasprowski.eyetracker.Window$1.run(Window.java:42)
at java.lang.Thread.run(Unknown Source)
Im feeding the method directly with images taken from camera (once a second).
EDIT:
After some experiments it occurs that from time to time when I invoke cvFindContours as above I get a contour object which IS NOT NULL but invoking any method like contour.h_next() or contour.total() results in exception like above. What can be wrong? Or - how to check if the contour object is OK?! Of course I could catch NullPointerException but I don't think it's a correct way to solve the problem...
Problem solved.
I added additional condition. Instead of:
if(contours!=null) {
I wrote
if(contours!=null && !contours.isNull()) {
and it works. I don't see exactly why it is necessary but I think it's connected with Java <-> C semantic gap.
Try to use cvGetSeqElem(contours, i)
Example :
for (int i = 0; i < contours.total(); i++) {
CvRect rect = cvBoundingRect(cvGetSeqElem(contours, i),0);
//....... Your code ....//
}

Categories