TileMap color is changing depending on Camera angle [UNITY] - visual-studio

Currently, I'm trying to highlight tiles around the outside of the object currently being dragged. I have tilemaps attached to the same object, one is the white border around the outside of the object and the other is the green center. The issue I am having at the moment is when the camera is facing the tiles at a set angle, the green tile will seem pale and at some coordinates. However, if I move the rotation or position of the camera, the pale tile will turn back to a solid green but turn pale again at another coordinate. I've attached two photos to show an example.
And here is the code involved with the tilemap:
//Reinitialize position to match TileMap orientation;
Vector3 newVec = new Vector3(pos.x, pos.z, 0);
Vector3 bottomRightPoint = newVec + new Vector3(1, 1, 0);
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
//if tile painting is the center player tile
if (i == 1 && j == 1) {
colourTileMap.color = selfTile;
colourTileMap.SetTile(Vector3Int.FloorToInt(bottomRightPoint - new Vector3(i, j, 0)), tile);
Debug.Log("selfTile" + selfTile);
}
tileMap.SetTile(Vector3Int.FloorToInt(bottomRightPoint - new Vector3(i, j, 0)), tile);
}
}
}
If you need any other information please feel free to reach out. Thanks in advance!

Related

Real-time object recognition in complex background

I'm trying to make a real-time advertisement billboard detection in road using android smartphone. The goal is to crop the area of the advertisement billboard object (regions of interest) and save it to database.
For example:
enter image description here
enter image description here
For preprocessing, I used grayscaling and Canny Edge Detection (Otsu thresholding is used to set the upper and lower threshold). Then, I used contour-based method to detect whether the object is rectangular by checking the point. I use Java OpenCV in android studio for implementation. When I run the program, it only detect rectangular object in plain background and if the rectangular having a high contrast from the background. Currently, it can only detect rectangle with 90 degree and it failed to detect object with rounded rectangle shape. Furthermore, my program failed completely to detect rectangular object in a more complex background, like road scene where the object I'm trying to detect is having similar color to the background/low contrast or there are many occlusions like tree, traffic light, and cables which caused the detection to fail.
This is the code I use for edge detection
Mat destination = new Mat(oriMat.rows(), oriMat.cols(), oriMat.type());
Imgproc.cvtColor(oriMat, destination, Imgproc.COLOR_RGBA2GRAY);
Imgproc.GaussianBlur(destination, destination, new Size(3,3), 0, 0, Imgproc.BORDER_DEFAULT);
double otsuThresholdValue = Imgproc.threshold(destination, destination, 0, 255, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);
double lowerThreshold = otsuThresholdValue*0.5;
double upperThreshold = otsuThresholdValue;
Mat canny = new Mat();
Imgproc.Canny(destination, canny, lowerThreshold, upperThreshold);
Mat abs = new Mat();
Core.convertScaleAbs(canny, abs);
Mat result = new Mat();
Core.addWeighted(abs, 0.5, abs, 0.5, 0, result);
Here is the code I use for contour-based detection
ArrayList<MatOfPoint> contours = new ArrayList<>();
// find contours and store them all as a list
Imgproc.findContours(matData.monoChrome.clone(), contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
final int width = matData.monoChrome.rows();
final int height = matData.monoChrome.cols();
int matArea = width * height;
for (int i = 0; i < contours.size(); i++) {
double contoursArea = Imgproc.contourArea(contours.get(i));
MatOfPoint2f approx = new MatOfPoint2f();
MatOfPoint2f contour = new MatOfPoint2f(contours.get(i).toArray());
double epsilon = Imgproc.arcLength(contour, true) * 0.1;
// Imgproc.minAreaRect(contour);
// approximate contour with accuracy proportional to the contour perimeter
Imgproc.approxPolyDP(contour, approx, epsilon, true);
if (Math.abs(contoursArea) < matArea * 0.01 ||
!Imgproc.isContourConvex(new MatOfPoint(approx.toArray()))) {
continue;
}
Imgproc.drawContours(matData.resizeMat, contours, i, new Scalar(0, 255, 0));
List<Point> points = approx.toList();
int pointCount = points.size();
LinkedList<Double> cos = new LinkedList<>();
for (int j = 2; j < pointCount + 1; j++) {
cos.addLast(angle(points.get(j % pointCount), points.get(j - 2), points.get(j - 1)));
}
Collections.sort(cos, (lhs, rhs) -> lhs.intValue() - rhs.intValue());
double mincos = cos.getFirst();
double maxcos = cos.getLast();
if (points.size() == 4 && mincos >= -0.3 && maxcos <= 0.5) {
for (int j = 0; j < points.size(); j++) {
Core.circle(matData.resizeMat, points.get(j), 6, new Scalar(255, 0, 0), 6);
}
matData.points = points;
break;
}
}
Is there any method I can use to recognize advertisement billboard in road?
I would appreciate any answers and ideas. Thank you!

Creating a view with shadow in a Processing game

I am writing a game for school project using Processing. I am currently dealing with a player's field of view. The player's field of view is basically a circle, but I would like the view to be blocked if there is an obstacle in front, meaning that you can't see the things behind the obstacle. The below image is the current results I have.
The link to the image
My code: http://pastie.org/10854654
The method I used is to go through every pixel in the player's field of view starting from the center, picking a path towards the circumference. As I searched outwards, if an obstacle is found on the path, I then draw a black line on the rest of the path. Changing the direction of the path degree by degree, eventually covering the whole circle.
//Draw a circle field of view.
int[][] collisionMap = map.getCollisionMap();
//Use a lot of small rectangle to cover the full map except of the circle field of view.
mainapplet.fill(0, 0, 0, 128);
for(int i = 0; i <= MyApplet.width; i++ ){
for(int j = 0; j <= MyApplet.height; j++ ){
if(mainapplet.dist(playerx, playery, i, j) > FieldOfView)
mainapplet.rect(i, j, 1, 1);
}
}
//Scan the circle field of view. If there is collision , draw a line to cover the area ,which means that the area is invisible.
mainapplet.stroke(0, 0, 0, 128);
mainapplet.strokeWeight(5);
for(float i = 0; i < 360; i+=1) {
for(float j = 0; j < FieldOfView ; j++ ){
float x = j * mainapplet.cos( mainapplet.radians(i) );
float y = j * mainapplet.sin( mainapplet.radians(i) );
if(collisionMap[player.getX() + (int)x ][player.getY() + (int)y ] == 1){
mainapplet.line(playerx + x, playery + y,
playerx + (FieldOfView-1)* mainapplet.cos( mainapplet.radians(i) ),
playery + (FieldOfView-1)* mainapplet.sin( mainapplet.radians(i) )
);
break;
}
}
}
collisionMap is a 2D array with 0s and 1s, "1" denoting that an obstacle is present at the location.
However, I find this method inefficient, therefore, causing lag. Is there a better way to do this? Or maybe there are already written tools that I can use?
What you're talking about is called 2d shadow mapping. It's not a trivial topic, but there are a ton of resources on google. I highly recommend reading up on them, because they'll explain it much better than I can.
But I did find this sketch on OpenProcessing which does what you describe. The full code is available at that link, but the pertinent bit seems to be this function:
void drawShadow() {
PVector tmp;
PVector m = new PVector(mouseX, mouseY); //mouse vector
fill(0);
stroke(0);
for (int i=0; i < vertCnt; i++) {
beginShape();
PVector v1 = p[i]; //current vertex
PVector v2 = p[i==vertCnt-1?0:i+1]; //"next" vertex
vertex(v2.x, v2.y);
vertex(v1.x, v1.y);
//current shadow vertex
tmp = PVector.sub(v1, m);
tmp.normalize();
tmp.mult(5000); //extend well off screen
tmp.add(v1); //true up position
vertex(tmp.x, tmp.y);
//"next" shadow vertex
tmp = PVector.sub(v2, m);
tmp.normalize();
tmp.mult(5000); //extend well off screen
tmp.add(v2); //true up position
vertex(tmp.x, tmp.y);
endShape(CLOSE);
}
}
But honestly the best thing you can do is google "processing shadow mapping" and spend some time reading through the results. This is a huge topic that's a bit too broad for a single Stack Overflow question.

Programmatically Load Texture in Image and Set Border to the Image Unity

I am developing a endless game, and want to take a Snapshot when the player Dies. I've almost done that using Texture2D. i have done Load Texture in image programmatically. but want to set border to the image. How can i do that.? how can i set border to that image at Run-time.?
This Code For Load Texture To the Image at Run-time when my player Dies.
void LoadImage(){
byte[] bytes = File.ReadAllBytes (Application.dataPath +"/GameOverScreenShot" + "/BirdDiedScreenShot.png");
Texture2D texture = new Texture2D (900, 900, TextureFormat.RGB24, false);
texture.filterMode = FilterMode.Trilinear;
texture.LoadImage (bytes);
Sprite sprite = Sprite.Create (texture, new Rect (0, 0, 700, 380), new Vector2 (0.5f, 0.0f), 1.0f);
imgObject.GetComponent<UnityEngine.UI.Image> ().sprite = sprite;
}
i want to Set Border to that image at Run-time. any one can help i really appreciate. thanks in Advance.
Do this after you load the image into the Texture2D variable and this will change the border of the image to whatever color you want.
//color should be a variable that holds the color of the border you want.
for (int i = 0; i< texture.width; i++){
texture.SetPixel(i, 0, color); //top border
texture.SetPixel(i, texture.height - 1, color); //bottom border
}
for (int j = 0; j < texture.height; j++){
texture.SetPixel(0, j, color); // left border
texture.SetPixel(texture.width - 1, j, color); //right border
}
texture.Apply();
This will replace any pixels on the edge of your original image so if you need those edge pixels you will need to look for another solution. Also, texture.Apply takes a while to run so if you need to constantly apply this border you may experience slowdown but you mentioned it is only when the player dies so this should not be an issue.

Three.js, center camera to view all objects that is in the scene

I write an algorithm that can explode (fold and unfold) mechanical set by double clicking on then.
But i want to move the camera backward or forward after that to see all my objects in the fov.
I'm trying to use frustum to calculate intersection between frustum and objects, but i don't undestand how to use planes.
I'm working with OrthographicCamera.
What i do :
At every frame i recalculate the new frustum (when camera move):
projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
frustum.setFromMatrix(projScreenMatrix);
Then i do a loop over the 6 planes and bounding box of all objects in the scene :
for (var i = 0; i < planes.length; i++) {
var plane = planes[i];
for (var j = 0; j < boxs.length; j++) {
var box = boxs[j];
var line = new THREE.Line3(box.min, nox.max);
//console.log({'plane': plane, 'line': line});
if (plane.isIntersectionLine(line))
// move camera
};
};
but plane.isIntersectionLine(line) is always false.
Do you have any ideas ?
Thanks

Emgu CV draw rotated rectangle

I'm looking for few days a solution to draw rectangle on image frame. Basically I'm using CvInvoke.cvRectangle method to draw rectangle on image because I need antialiased rect.
But problem is when I need to rotate a given shape for given angle. I can't find any good solution.
I have tryed to draw rectangle on separate frame then rotate hole frame and apply this new image on top of my base frame. But in this solution there is a problem with antialiasing. It's not working.
I'm working on simple application that should allow draw few kinds of shape, resize them and rotation for given angle.
Any idea how to achive this?
The best way I found to draw a minimum enclosing rectangle on the contour is using the Polylines() function which uses vertices that are returned from MinAreaRect() function. There are surely other ways to do it as well. Here is the code walk down:
// Find contours
var contours = new Emgu.CV.Util.VectorOfVectorOfPoint();
Mat hierarchy = new Mat();
CvInvoke.FindContours(image, contours, hierarchy, RetrType.Tree, ChainApproxMethod.ChainApproxSimple);
// According to your metric, get an index of the contour you want to find the min enclosing rectangle for
int index = 2; // Say, 2nd index works for you.
var rectangle = CvInvoke.MinAreaRect(contours[index]);
Point[] vertices = Array.ConvertAll(rectangle.GetVertices(), Point.Round);
CvInvoke.Polylines(image, vertices, true, new MCvScalar(0, 0, 255), 5);
The result can be visualized in the image below, in red is the minimum enclosing rectangle.
I use C# and EMGU.CV(4.1), and I think this code will not be difficult to transfer to any platform.
Add function in the in your helper:
public static Mat DrawRect(Mat input, RotatedRect rect, MCvScalar color = default(MCvScalar),
int thickness = 1, LineType lineType = LineType.EightConnected, int shift = 0)
{
var v = rect.GetVertices();
var prevPoint = v[0];
var firstPoint = prevPoint;
var nextPoint = prevPoint;
var lastPoint = nextPoint;
for (var i = 1; i < v.Length; i++)
{
nextPoint = v[i];
CvInvoke.Line(input, Point.Round(prevPoint), Point.Round(nextPoint), color, thickness, lineType, shift);
prevPoint = nextPoint;
lastPoint = prevPoint;
}
CvInvoke.Line(input, Point.Round(lastPoint), Point.Round(firstPoint), color, thickness, lineType, shift);
return input;
}
This draws roteted rectangle by points. Here used rounding points by method Point.Round becose RotatedRect has points in float coordinates and CvInvoke.Line takes points as integer.
Use:
var mat = Mat.Zeros(200, 200, DepthType.Cv8U, 3);
mat.GetValueRange();
var rRect = new RotatedRect(new PointF(100, 100), new SizeF(100, 50), 30);
DrawRect(mat, rRect,new MCvScalar(255,0,0));
var brect = CvInvoke.BoundingRectangle(new VectorOfPointF(rRect.GetVertices()));
CvInvoke.Rectangle(mat, brect, new MCvScalar(0,255,0), 1, LineType.EightConnected, 0);
Result:
You should read the OpenCV documentation.
There is a RotatedRectangle class that you can use for your task. You can specify the angle by which the rectangle will be rotated.
Here is a sample code (taken from the docs) for drawing a rotated rectangle:
Mat image(200, 200, CV_8UC3, Scalar(0));
RotatedRect rRect = RotatedRect(Point2f(100,100), Size2f(100,50), 30);
Point2f vertices[4];
rRect.points(vertices);
for (int i = 0; i < 4; i++)
line(image, vertices[i], vertices[(i+1)%4], Scalar(0,255,0));
Rect brect = rRect.boundingRect();
rectangle(image, brect, Scalar(255,0,0));
imshow("rectangles", image);
waitKey(0);
Here is the result:

Resources