I have working code in Visual Studio with C ++ on a watershed algorithm and I need to pass it to Android Studio. I have added the OpenCV library to the app and the simple operations work. Now, my problem is that when I want to pass the code to Java there is a specific line type that I don't know how to pass. The part of the code is:
cv::Mat markers(original.size(), CV_8U, cv::Scalar(-1));
//Rect(topleftcornerX, topleftcornerY, width, height);
//top rectangle
markers(Rect(0, 0, original.cols, 5)) = Scalar::all(1);
//bottom rectangle
markers(Rect(0, original.rows - 5, original.cols, 5)) = Scalar::all(1);
//left rectangle
markers(Rect(0, 0, 5, original.rows)) = Scalar::all(1);
//right rectangle
markers(Rect(original.cols - 5, 0, 5, original.rows)) = Scalar::all(1);
What would be the creation of the object would be something like this:
Mat markers = new Mat(rgba.size(), CvType.CV_8UC3, new Scalar(-1));
But the rest of the lines do not know how they would be transformed. Help please?
markers.submat(0, 0, original.cols, 5).setTo(new Scalar(1, 1, 1));
or
Imgproc.rectangle (
markers,
new Point(0, 0),
new Point( original.cols, 5),
new Scalar(1, 1, 1),
-1
);
Related
I studied this question, but I still don't get it. The shortest possible code below shows a Pyramid totally grey, whereas I try to give the 6 triangles making up the pyramid different colors. So ... why don't these colors show up?
Note that I borrowed the getTexCoords().addAll(..) statement from that question, but clearly I still am doing something wrong. Is it the uv mapping? What is that anyway? I have seen a topological explanation (sphere <-> map), but what has that got to do with textures/colors...?
Appreciate your help - Michael
public class ColoredPyramid extends Application {
public void start(Stage primaryStage) {
Group root = new Group();
Scene scene = new Scene(root, 200, 200, true);
primaryStage.setTitle("Colored Pyramid");
primaryStage.setScene(scene);
primaryStage.show();
TriangleMesh colouredPyramid = new TriangleMesh();
float height = 100;
float hypotenuse = 150;
colouredPyramid.getPoints().addAll(0, 0, 0); //0-index:: top
colouredPyramid.getPoints().addAll(0, height, -hypotenuse / 2); //1-index:: x=0, z=-hyp/2 ==> Closest to user
colouredPyramid.getPoints().addAll(-hypotenuse / 2, height, 0); //2-index:: x=hyp/2, z=0 ==> Leftest
colouredPyramid.getPoints().addAll(hypotenuse / 2, height, 0); //3-index:: x=hyp/2, z=0 ==> rightest
colouredPyramid.getPoints().addAll(0, height, hypotenuse / 2); ////4-index:: x=0, z=hyp/2 ==> Furthest from user
//Next statement copied from stackoverflow.com/questions/26831871/coloring-individual-triangles-in-a-triangle-mesh-on-javafx
colouredPyramid.getTexCoords().addAll(
0.1f, 0.5f, // 0 red
0.3f, 0.5f, // 1 green
0.5f, 0.5f, // 2 blue
0.7f, 0.5f, // 3 yellow
0.9f, 0.5f // 4 orange
);
colouredPyramid.getFaces().addAll(0, 0, 2, 0, 1, 0); //Left front face ---> RED
colouredPyramid.getFaces().addAll(0, 1, 1, 1, 3, 1); //Right front face ---> GREEN
colouredPyramid.getFaces().addAll(0, 2, 3, 2, 4, 2); //Right back face ---> BLUE
colouredPyramid.getFaces().addAll(0, 3, 4, 3, 2, 3); //Left back face ---> RED
colouredPyramid.getFaces().addAll(4, 4, 1, 4, 2, 4); //Base: left triangle face ---> YELLOW
colouredPyramid.getFaces().addAll(4, 0, 3, 0, 1, 0); //Base: right triangle face ---> ORANGE
MeshView meshView = new MeshView(colouredPyramid);
Group group = new Group(meshView);
group.setTranslateX(100);
group.setTranslateY(80);
root.getChildren().add(group);
}
public static void main(String[] args) {
launch(args);
}
}
To understand how JavaFX 3D defines the color of any given 3D shape, have a look at the PhongMaterial javadoc (bold is mine):
The PhongMaterial class provides definitions of properties that represent a Phong shaded material. It describes the interaction of light with the surface of the Mesh it is applied to. The PhongMaterial reflects light in terms of a diffuse and specular component together with an ambient and a self illumination term. The color of a point on a geometric surface is mathematical function of these four components.
That means that you need to supply a material in the first place, and then you need to specify any of those components, for instance the diffuse component.
If you copy the image from the cited question:
and create a material instance with it:
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(new Image(getClass().getResourceAsStream("bB2jV.png")));
meshView.setMaterial(material);
you can see that this image is used to apply colors to your pyramid:
If you modify the texture indices for the faces, you will get different colors, based on the texture coordinates.
To know more about this, you can have a look at the FXyz3D library, that provides a TexturedMesh class based in this concept. There you will find many different 3D shape "textured" primitives, that can use different texture "modes". Most of those modes don't even require an image, as this is created internally. This allows creating for instance color gradients based on mathematical functions.
This is an example of a TetrahedraMesh, that makes use a 3D function to define the density map:
TetrahedraMesh tetra = new TetrahedraMesh(10, 5, null);
tetra.setTextureModeVertices3D(1530, p -> p.magnitude());
My libgdx game has a laser and I want to know if the beam hits it's target.
I had some trouble with the function (always getting true) so I made a very simple test and I still get true!
Did I miss something?
Why is this function returning true?
if(Intersector.intersectLinePolygon(new Vector2(100, 100), new Vector2(200, 100), new Polygon(new float[] {0, 0, 5, 0, 5, 5}))) {
System.out.println("true");
}
Thanks in advance!
I got caught by this when I first used Intersector too.
The intersectLinePolygon() method works on a line that extends infinitely, and not just between the two points you specify.
Use the intersectSegmentPolygon() method which does what you want...
if(Intersector.intersectSegmentPolygon(new Vector2(100, 100), new Vector2(200, 100), new Polygon(new float[] {0, 0, 5, 0, 5, 5}))) {
System.out.println("true");
}
I'm using opencv and java to find circles on an image, I have the image below so far.
I'm using Hough to find the circles with the code like this:
Imgproc.medianBlur(result, result, 3);
Imgproc.medianBlur(result, result, 3);
Imgproc.medianBlur(result, result, 3);
Mat circles = new Mat();
Imgproc.HoughCircles(result, circles, Imgproc.CV_HOUGH_GRADIENT, 1, 1, 200, 100, 30, 40);
System.out.println(circles.dump());
But I get an empty Mat for result with and without the blur.
How should I fix this code?
EDIT :
Hi guys!
Thanks to you I have this picture now. I'm using these parameters:
Imgproc.HoughCircles(result, circles, Imgproc.CV_HOUGH_GRADIENT, 1, 20, 50, 10, 10, 40);
I'm still using the medianBlur before the detection.
The only question left is why does it detect these small circles? I've attached the result of the canny detection, I think the circles are pretty seeable .
First of all, the circles structure should not be cv::Mat but should be std::vector<cv::Vec3f>; I think that is why you aren't getting any results.. Please refer to the documentation on the HoughCircles for details..
Playing around with the values for 5 minutes, I have this starting point for you:
The parameters I used are,
cv::medianBlur(test_Circle, test_Circle, 7);
std::vector<cv::Vec3f> circles; // <- not that "circles" is not cv::Mat
cv::HoughCircles(test_Circle, circles, CV_HOUGH_GRADIENT, 1, 1, 300, 10, 10, 50);
You can get much more defined result after you played around with the values a bit.
PS - Since I am a C++ user, please excuse me for putting all my structures in that format. You can easily extend the logic to Java. :)
Are you sure you are providing radius and not diameter? Try wider range of radiuses (10-100 for example).
Using OpenCV to cheat in Zuma? :)
I've tested my code, it writtent in C# (i think java is the same) and get the result:1
You can find my code in HoughAlgorithm.cs class
My demo Project Here
//DP_Resolution: 1
//MinDistance :32
//CannyThreshold: 10
//AccuThreshold: 10
//MinRadius: 13
//MaxRadius: 20
public static CvSeq DetectCircles(IplImage pImage, CamEnum _camName)
{
try
{
CvMemStorage memStorage = cvlib.CvCreateMemStorage(0);
return cvlib.CvHoughCircles(ref pImage, memStorage.ptr, 3, 1, 32, 10, 10, 13, 20);
}
catch
{
throw;
}
}
http://i.stack.imgur.com/pUqbh.png
This code is OpenCV c++:
lines = cvHoughCircles(frame2, storage, CV_HOUGH_GRADIENT, 1, 50, 300, 60, 10, 600);
for (int i = 0; i < lines.total(); i++) {
//Would like the code to go here
CvPoint2D32f point = new CvPoint2D32f(cvGetSeqElem(lines, i));
cvCircle(src, cvPoint((int)point.x(), (int)point.y()), 3, CvScalar.WHITE, -1, 8, 0);
Point p = new Point((int)point.x(), (int)point.y());
points.add(p);
}
What is the correspondent in the new Java Api? I cannot get CvPoint2D32f, cvGetSeqElem and CV_AA. I found that existed in JavaCV but cannot find them in OpenCV Java api.
Thanks
EDIT:
I've changed my code and now I have:
MatOfPoint3 circles = new MatOfPoint3();
Imgproc.HoughCircles(image, circles, Imgproc.CV_HOUGH_GRADIENT,2, image.rows()/4,200,100,0,0);
for(Point3 circle : circles.toArray()){
Point center = new Point(circle.x, circle.y);
int radius = (int) Math.round(circle.z);
Core.circle(image, center, radius, new Scalar(0,255,0), 6, 8, 0);
}
However I got an error at for(Point3 circle : circles.toArray()):
Exception in thread "main" java.lang.UnsupportedOperationException: Mat data type is not compatible: 21
at org.opencv.core.Mat.get(Mat.java:2581)
at org.opencv.core.MatOfPoint3.toArray(MatOfPoint3.java:64)
at org.opencv.core.MatOfPoint3.toList(MatOfPoint3.java:76)
at main.java.DetectFaceDemo.run(HelloOpenCV.java:60)
at main.java.HelloOpenCV.main(HelloOpenCV.java:83)
Any thoughts on this? Thanks
EDIT 2:
The solution to last edit problem resides in
MatOfPoint3 circles = new MatOfPoint3();
It must be
MatOfPoint3f circles = new MatOfPoint3f();
Use Class Point3. Template class for 3D points specified by its coordinates x, y and z. An instance of the class is interchangeable with the C structure CvPoint2D32f. Similarly to Point_, the coordinates of 3D points can be converted to another type. The vector arithmetic and comparison operations are also supported.
I am creating custom SWT widget but I have got problem with transparency. My class extends canvas, I have got png with alpha image in my resources, when I simply write:
this.setBackgroundImage(Colors.getMenuButton()); //getMenuButton returns Image object
everything works ok (with transparency), but my object has to be resizeable so I decided to create funcion:
protected Image BGHelper(Image src) {
Image i2 = new Image(Display.getDefault(),2,26);
GC gc2 = new GC(i2);
Image image = new Image(Display.getDefault(),this.getBounds().width,26);
GC gc = new GC(image);
gc.drawImage(src, 0, 0, 3, 25, 0, 0, 3, 26);
gc2.drawImage(src, 3, 0, 2, 25, 0, 0, 2, 26);
gc.drawImage(i2, 0, 0, 2, 25, 3, 0, this.getBounds().width-6, 26);
gc.drawImage(src,53, 0, 3, 26, this.getBounds().width-3, 0, 3, 26);
gc.dispose();
gc2.dispose();
return image;
}
it cuts left border from source and paste into result, cut center from source, resize and paste into result, cut right border from source and paste into result. Resizing works but there is no transparency (white pixel). Why?
please look at following doc.It might help you to solve your issue.
http://www.eclipse.org/articles/Article-SWT-images/graphics-resources.html#Transparency