I'm trying to extract and plot some points on a raster.
I did the following:
library(sp)
pt1 <- data.frame(cbind(4110000,40000))####almost completely degraded
pt2 <- data.frame(cbind(4100000,0))#####green
pt3 <- data.frame(cbind(4140000,55000))####slightly green
pt <- rbind(pt1, pt2, pt3)
coordinates(pt) <- c("X1","X2")
points(pt)
But, the line:
coordinates(pt) <- c("X1","X2")
is giving that error which is affecting the plotting:
Error in coordinates<-(*tmp*, value = c("X1", "X2")) :
setting coordinates cannot be done on Spatial objects, where they have already been set.....
Any advice please?
Your code works fine. The error only happens when you run this row twice:
coordinates(pt) <- c("X1","X2")
To plot these on top of a raster r
plot(r)
points(pt)
Related
I am doing a project where I need to draw a laser line image on a graph. I got the coordinates of the laser points. I am going to draw a two-dimensional graph in the Halcon (MVTEC software) using points
Some points are duplicates and this prevents the diagram from being drawn correctly. How can I remove duplicate points? And draw a diagram with X and Z axes?
Please download the coordinate file via the link below:
https://s21.picofile.com/d/8445324542/15c1902a-0828-4692-b0ce-a65651306111/Coordinates.rar
There are actually no duplicate points in your dataset. The problem is that your data is essentially sorted by the wrong axis. You can re-sort and plot them like this:
read_tuple ('Rows.tup', Rows)
read_tuple ('Columns.tup', Cols)
* dev_inspect_ctrl (['plot_xy', Cols, Rows])
Indices := sort_index(Cols)
Rows2 := Rows[Indices]
Cols2 := Cols[Indices]
dev_get_window (WindowHandle)
plot_tuple (WindowHandle, Cols2, Rows2, [], [], [], [], [])
I'm sorry for the title, that maybe can't describe properly what I would like to achieve. I'm starting to develop a new software which should present a "grid" to the user that can be manipulated by him adding "rows" or "columns" in any point of this "grid". The problem is that I'm not sure a real grid is the suitable solution, because there are some "graphical" requirements like changing invididual cells sizes, nesting them, zooming/stretching, etc. So I was starting to analyze a solution in WPF that uses DrawingVisual elements (for performance reason).
I'm able to draw the "grid" in the desired way. I'm also able to add rows or columns at the edges of the drawing. But I can't figure any solution to modify it in the "middle" (except redrawing the whole thing). I'll explain me better with an image. On the left there's the "grid" after it has been drawn for the first time. On the right there's a new grid that should be drawn after the user performs an operation.
An more complex example is the following, where the "row" is added inside an existing cell, causing all the cells to "grow".
As I said, I know I could redraw the whole thing, but I'm concerned about performance. Keep in mind that in a real scenario there could be thousands of blocks and many nesting levels.
Any suggestion is appreciated. The use of WPF is not mandatory, but it will be a desktop app in .NET 5.0. The use of a DrawingVisual is neither mandatory. I can evaluate any solution. Thank you.
A simple technique is to keep positions of columns relative to the left of the canvas in a variable when you first draw the tables. When you want to add a new column, you can crop the image from that point, and in a larger canvas, copy the left and right pieces and just draw the middle column from the beginning.
Of course, the coordinates of each column can be calculated with image processing techniques, but it reduces performance.
I wrote this code with Python, but I do not think it would be difficult to convert it to C#.
import cv2
import numpy as np
# copy image over another
def imdraw(im, over, x, y):
y1, y2 = y, y + over.shape[0]
x1, x2 = x, x + over.shape[1]
for c in range(0, 3):
im[y1:y2, x1:x2, c] = over[:, :, c]
return im
pt = 220
col = 300
off = 15
im = cv2.imread("grid.png", 1)
h, w = im.shape[:2]
crop_left = im[0 : 0 + h, 0:pt]
crop_right = im[0 : 0 + h, pt:w]
cv2.imwrite("left.jpg", crop_left)
cv2.imwrite("right.jpg", crop_right)
# Create an Empty image with white background
out = 255 * np.ones(shape=[h, w + col, 3], dtype=np.uint8)
out = imdraw(out, crop_left, 0, 0)
out = imdraw(out, crop_right, pt + col, 0)
out = cv2.rectangle(
out,
pt1=(pt + off, off),
pt2=(pt + col - off, h - off),
color=(128, 0, 200),
thickness=5,
lineType=cv2.LINE_AA,
)
cv2.imwrite("out.jpg", out)
Output:
I need to find the value along a vector for a given x coordinate. Like so;
I know the values of A, B and C. All of these value are variable. I need to calculate X. I know this is possable I just can't remember my trigonometry lessons.
I'm aware of similar questions like this one but it only finds the mid-point.
Thank you.
Lets say A(x1,y1) and B(x2,y2)
and co-ordinates of X(x,y) , then:
y = ((y2-y1)/(x2-x1))x + c .....(1)
where c is the y intercept, which in this case is 0.
y = ||C-A|| / ||D-A||
Z = (B - A) * y
Where y = length of vector C minus vector A, divided by length of D(unlabeled original length along x axis) minus vector A
For a line through the origin, as you have in the picture, you can use the idea of similar triangles:
X_y = B_y * (X_x/B_x)
Or, for the numbers shown in the example, X_y = 50, and X=(50,50).
To understand this, similar triangles says:
X_y/X_x = B_y/B_x
since triangles with similar shapes (ie, that have the same angles), have the same ratios; and the first formula is just solving the second to give X_y.
(If the line isn't through the origin, first subtract A from everything, then calculate X_y as above, then add A to everything.)
I have a series with many null values all over the place on the line. I need the gap between those values to be represented with a dotted-line or whatever (another color).
Any help will be very welcome :)
thanks!
Before starting, let me confess that its an interesting problem but very much solvable using Highcharts. Though this will need a bit of work.
This is how I would implement this:
Algo:
For every series S, create an another auxiliary series S'. S' job is to fill the gaps. S' can be a dotted line of same color. For every gap, consecutive nulls, in S, let say gap starts at point L(x1,y1) and ends at point R(x2,y2). Points L and R needs to be there on S'. Lets say points L and R are m units away from each other where m>=2. We need to insert m-1 points between L and R. We can do this by linear interpolation. We will call these points as P1, P2 .. Pm-1 where Pi = { x2-x1 + i, y1 + (y2 -y1)/m }
Usability:
If lets say you have series T, Q, R ans S in your original chart. After application of above algorithm, you will have 4 more series named T', Q', R' ans S'. In legend, 8 series will be visible. But we want only 4 - the original ones. You can accomplish this by using 'linkedTo' property of series. So T' will be linked to T, S' will be linked to S and so on. As a result, legend of S' will not be shown and when you toggle S by clicking legend, S' will automatically toggle.
linkedTo : http://api.highcharts.com/highstock#plotOptions.series.linkedTo
Location of code:
As mentioned in algo, you need to read existing series and insert auxiliary series. You can do this in the load() callback function which is called when the chart has finished loading and all the series are available to access.
Load Callback : http://api.highcharts.com/highstock#chart.events.load
Adding a series : http://api.highcharts.com/highstock#Chart.addSeries()
Cheers!
I am trying to draw a bounding box around the white blob in the image below:
I did like this:
bw = imread('box.jpg');
bw=im2bw(bw);
imshow(bw)
L = bwlabel(bw);
s = regionprops(L, 'Area', 'BoundingBox');
s(1);
area_values = [s.Area];
idx = find((100 <= area_values) & (area_values <= 1000)); % list of all the objects
%whose area is between 100 and 1000
bw2 = ismember(L, idx); %construct a binary image containing all the objects whose
%area is between 100 and 1000 by passing L and idx to ismember.
imshow(bw2)
The output bw2, so far is:
Can someone one tell me how to draw a bounding box around this blob(white)?
Update
Wajih's answer actually accurately solved the issue.
Pseduo -
Pick largest y, largest x, smallest x, smallest y with in the blob. That is, points on the blob. These are your coordinates that you can use to build the bounding box.
assuming top left of image as (0,0)
(smallestX,smallestY)-----------------(largestX,smallestY)
| |
| |
| |
| |
(smallestX,largestY)------------------(largestX,largestY)
And for finding minimum/maximum values and indices.
[r,c]=find(img==min(min(img)))
[r,c]=find(img==max(max(img)))
r,c represent row and column in the img matrix.
I have marked the points on your image that you can use to create the bounding box.
Zoomed Image to get a better view.
As the 20,000th viewer of this question, I'll answer what I think the asker is actually asking.
To render a rectangle on the page, you just need to properly interpret the bounding box for the shape. You've already computed this in s(idx).BoundingBox
Thus, add these two lines to your script:
bb = s(idx).BoundingBox;
rectangle('Position',[bb(1) bb(2) bb(3) bb(4)],'EdgeColor','green');
and you'll get:
Have you tried regionprops from Image Toolbox?
I think you can try to use bwboundries
boundaries = bwboundaries(blob);
numberOfBoundaries = size(boundaries);
for k = 1 : numberOfBoundaries
thisBoundary = boundaries{k};
plot(thisBoundary(:,2), thisBoundary(:,1), 'g', 'LineWidth', 2);
end