Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
It so confusing to understand or imagine this explanation. is there a picture to describe this?. what it means left, top, right, bottom? i knows rectangle have four corner. the more confusing with subraction. rect can get width, and height.
https://learn.microsoft.com/en-us/windows/win32/api/windef/ns-windef-rectl
left:
Specifies the x-coordinate of the upper-left corner of the rectangle.
top:
Specifies the y-coordinate of the upper-left corner of the rectangle.
right:
Specifies the x-coordinate of the lower-right corner of the rectangle.
bottom:
Specifies the y-coordinate of the lower-right corner of the rectangle.
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
A rectangle described by RECT structure has its sides parallel to screen edges.
Left, Right, Top and Bottom are distances (usually in pixel) from top-left screen corner.
You can also see it as defined by two corner points, Top;Left and Bottom;Right. The other two would repeat coordinates from these two, so they are not needed.
Related
Following Problem:
Let's say we have a rectangular map containing several rectangles.
I want to find all possible "maximal" rectangles which can be placed on the map without intersecting any of the other rectangles. With maximal I mean rectangles which can't be enlarged in any direction.
Does someone know an algorithm to perform this task?
enter image description here
I'll suggest a solution that may not be the faster but should do the job.
The idea is to place each of your rectangles one by one. Everytime you add a rectangle in the map, check if it intersects any of the others. If it does, then just break these both rectangles into the correct corresponding new rectangles, depending on the shape of the intersection.
It's easy to see that if a new rectangle (green) covers the whole affected rectangle (red), only the new would be broke apart. Otherwise, both will.
Just by adding one by one and breaking them apart correctly, you will have your full set of rectangles in the end, which you just need to iterate to find your "maximal", if it means the ones with biggest area.
This algorithm should be something around O(n²) where n is the number of rectangles you add.
You can do this with simple interval algebra. For illustration, I'll put some numbers on the example you gave us. I'll use the Cartesian first quadrant, origin in the lower-left corner. The entire field is then (0, 0) to (30, 20); rectangles have corners at (10, 0) to (30, 8); (0, 12) to (13, 20); (20, 15) to (25, 17).
To solve this, group rectangle edges by their orientation with respect to their rectangles; specifically, which direction they face (away from the rectangle's center). Edges of the window face inward. This gives us four sets, one for each "facing" direction. An edge is described with the common coordinate in one direction and a range in the other. I'll keep them in the same x-y notation. For instance, sorted by y-coordinate:
bottom low-rt up-rt
face_up = (0-10, 0), (10-30, 8), (20-25, 17)
The top edge of the top rectangle coincides with the top of the window; it faces up,. but has no room for a white rectangle.
Similarly, the down-facing edges are
up-left up-rt top
face_down = (0-13, 12), (20-25, 15), (13-30, 20)
Now it's a simple matter to match each rectangle edge with the first one that blocks its open region. For instance, consider the low-rt rectangle's face_up edge, (10-30, 8) We compare to face_down edges in order of y-coordinate, starting with y >= 8.
(0-13, 12) is the first y > 8 edge. Checking x intervals, we see that [0, 13] and [10-30] do overlap; we have a block with corners at (10, 8) and (12, 13) to expand sideways in each direction. This results in your blue rectangle.
Similarly, we will match the (face_up) left side of the window bottom with the same face_down edge. This results in your orange rectangle. Then we match the top of the up-rt (smallest) rectangle with the window top: green rectangle.
Continuing in the opposite direction, we find that two face_down edges match existing rectangles. We also match the bottom of the up-rt rectangle with the top of the low-rt rectangle, yielding the yellow rectangle.
Repeat this process with the face_left and face_right edges to obtain the red and purple rectangles, as well as a second hit of the orange rectangle.
Is that enough of an outline for you to implement?
Sorting the edges in order gives us the ability to do a linear search from each edge. If I'm casting this code properly, the result is an O(N) algorithm for N rectangles, although the original edge sorting is O(log N).
I have tried and failed to find an Applescript code that returns a smart object's current rotation angle in Photoshop. Anyone have an idea of where that property is listed? I'm beginning to think this feature isn't currently supported by Applescript.
In Photoshop, objects like a selection has no angle value, because it means nothing: if your selection is made by multiple segments making a complexe shape, there is no mathematical way you can define angle for that shape !
However, you can work with boundary rectangle (which includes that shape). You can rotate this complete boundary (i.e. the selection) and then you will get a new boundary (new rectangle where new rotated shape fits in).
A boundary rectangle is made of a list of for values :
top left corner horizontal position (X1)
top left corner vertical position (Y1)
bottom right corner horizontal position (X2)
bottom right corner vertical position (Y2)
Positions are real numbers, starting with border of canvas (not border of layer ! so you may have negative values). The units depends of the unit of measure of the document.
Once that's clear (I hope !) if you use mathematical calculation between initial boundary and new boundary, you can calculate the rotation angle:
(Pythagore triangle)
If you assume that initial rectangle borders were vertical and horizontal :
cosinus (Teta) = (X2-X1) / (X'2 - X'1)
Teta = angle you are looking for
X1, X2 are the positions of the boundary corners before rotation and X'1, X'2 are position of same corners after rotation.
Please note that this method is OK for selection (any shape), or layers.
It should also be OK for the full canvas, but I never test it for canvas.
There is a problem:
Have a rectangle, the coordinates of the lower left corner - (0, 0), upper right (width of the rectangle, the height of the rectangle). Inside this rectangle is the point having certain coordinates. I need to draw around this point a segment of a circle with a certain (const) arc length. Calculate the internal radius and the angle of the segment of a circle.
illustration:
Like this. As can be seen from the figure, if the segment to be placed in the side of the screen (eg bottom left), it is necessary to find such a range that it satisfies our long arc.
Prompt, in what side to search?
Thank you in advance.
I am writing a small image analysis program just for fun. Image analysis has always fascinated me. I am trying to locate regions on a scanned document. These regions are going to be marked by clearly defined filled black rectangles (pre-printed on the page).
My problem is locating the rectangles. I know SIFT\SURF find "features" but I am trying to find something specific. Here is what I was thinking of doing. I am not sure if this is the "right" way or there is a better idea.
First off using some library I will turn the image into greyscale, perhaps a PGM since that is what I'm used to working with in school. For the analysis I first plan to run the image through a state of the art deskew algorithm in OpenCV or something else that I find. Once I have my deskewed image I will then threshhold it at some pretty high thresshold. The rectangles are going to be straight black hence me using a pretty high threshhold. I will then experimentally determine a good size black rectangle to slide across the image. While sliding my rectangle across the image I will determine the areas where the greatest percentage of pixles are the same. I will have a cutoff, say 90%. If 90% of the pixles contained in my window are black I must have found a rectangle. My reasoning is that a true black rectangle slid over something that is "pretty much" a black rectangle is most likely a black rectangle. Since I deskewed the image I can assume that the rectangles are straight up and down "enough". I can then track the (x,y) offsets where the rectangles are found on the image and mark them.
Would anyone suggest a better approach?
There are many approaches that might work. (One can easily come up with 10 or more approaches.)
Idea #1 - Canny edge detection; find rectangle fit to contours
cv::Canny
cv::findContours
cv::minAreaRect, or
cv::boundingRect might also work, if the deskewing works as advertised.
Idea #2 - Find all lines using Hough transform; Iterates through all regions created from line intersections.
Idea #3 - (Improvement on #2) Restrict the Hough transform to horizontal and vertical lines by pre-processing.
Idea #4 - Compute Horizontal and Vertical profiles on the entire image; find dips; iterate through all candidate regions.
This idea is based on the assumption that the black rectangles are large enough that they leave a "depression" in both the horizontal and vertical projection profiles, which would be detectable despite other noise objects in the image.
cv::reduce
With dim = 0 or 1 for reducing to a row or column respectively,
With CV_REDUCE_AVG flag
Apply cv::threshold to the horizontal and vertical projection profiles, separately.
For each profile now thresholded into zero/non-zero, find runs of zeroes. These are the possible row ranges and column ranges that could contain the dark rectangles.
For each combination of candidate row range and column range, calculate the average pixel value to decide if it is a true dark rectangle.
Idea #5 - Use integral image (summed area table) to quickly calculate the average pixel value in arbitrary rectangles
cv::integral
To compute the sum (and average) of a rectangle from an integral image, see the Wikipedia article on Summed Area Table
Preprocessing idea - use morphological dilation (or erosion) to "erase" things that cannot be the large continuous black box.
Preprocessing idea - use pre-processing to enhance horizontal and vertical edges; suppress edges in other directions.
I don't know if it is a better approach, but the first thing that came to mind would be a scan-line solution (assuming black or white pixels): I'd check each scanline from top to bottom. In each scanline I'd check each pixel from left to right. A "first" black pixel would be a possible upperleft corner of a rect. If there were enough following contiguous black pixels on the line to meet my desired minimum width, keep the [left, width] in a list of possible rects. Find all possible rect starts and widths on the line.
For a rect to stay in the list and grow in height, the next scanline would have to have the same [left, width] occurrence, otherwise the rect is finished (if its height meets my desired minimum height) or discarded or ignored as too short in height.
You can easily add logic for situations like two rectangles too close to one another vertically or horizontally. Overlapping rectangles would be trickier but still possible to detect with added code.
Here's some pseudocode:
for s := 1 to scanlinecount do
begin
pixel := 1
while pixel <= scanlinewidth do
if black(s, pixel) then // possible rect
begin
left := pixel
repeat
inc(pixel)
until (pixel > scanlinewidth) or white(s, pixel)
width := pixel - left
if width >= MINWIDTH then // wide enough
rememberrect(s, left, width) // bumps height if already in list
end
else inc(pixel)
end
Your list of found rects stores the starting scanline, leftmost pixel, width, and height for each rect found. The "rememberrect" routine checks each rect in the list:
rememberrect(currentline, left, width):
for r := 1 to rectlist.count do
if rectlist[r].left = left
& rectlist[r].width = width
& rectlist[r].y + rectlist[r].height = currentline then
begin // found rect continuing on scanline
inc(rectlist[r].height)
exit
end
inc(rectlist.count) // add new rect to list
rectlist[rectlist.count].left := left
rectlist[rectlist.count].width := width
rectlist[rectlist.count].y := currentline
rectlist[rectlist.count].height := 1
If the group of black pixels on the current scanline has the same leftmost pixel and width as a group on the previous scanline (you'll know they're vertically contiguous because the starting scanline of the rect in the list plus its height will equal the current scanline) then rememberrect bumps the height of the found and remembered rect by 1. Otherwise, remember the new rect with initial height 1.
After the last scanline you'll have a long list of rect candidates, many of them only 1 pixel high. Delete or ignore any rects in the list that aren't high enough. To avoid growing a long list of futile candidates: at the start of each scanline mark all rects found so far as "finished". If rememberrect grows an existing rect or adds a new rect, mark that rect as "grown". At the end of each scanline, any rect still marked as finished that isn't tall enough can be deleted from the list.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions must demonstrate a minimal understanding of the problem being solved. Tell us what you've tried to do, why it didn't work, and how it should work. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Provided a complex shape of irregular form, drawn on a 2D surface (let's say a canvas). Provided also a point on that canvas in form of coordinates (e.g. a coordinate of a mouse click).
How to determine if the point resides inside, on the edge or outside of the said object.
For simplicity, let's consider the edge to be one pixel (point) wide.
To facilitate the question and suggest the level of complexity, let's consider a shape as shown on the image below.
So, to sum up:
Is the point with given coordinates inside the shape?
Is it on the edge?
Or is it outside of the shape?
One possible strategy:
Flood-fill the exterior to some color, say red.
Any black pixel touching a red pixel is an external border pixel.
Any black pixel touching a white pixel is an internal border pixel.
All other black pixels are interior to the object.
Points 2–4 can be evaluated concurrently in a single scan of the image.
If you want to do this really fast, you can use OpenGL with an evaluative fragment shader. But that's a bit more involved.
In matlab
l = bwlabel( img, 4 ); % label white regions using 4-connect neighbors
[or oc] = find( (l == 0) & imdilate( l == 1, strel('disk',1,0) ) ); % outer boundary
[ir ic] = find( (l == 0) & imdilate( l == 2, strel('disk',1,0) ) ); % inner boundary
I posted some flood-fill algorithm here. Hope this can help.
I didn't try it, but try to do a pseudo- edge detection by:
filter=[0 -1 0 ; -1 4 -1 ; 0 -1 0];
newImage=conv2(yourImage,filter);
It suppose to keep only (or mainly) the outer and inner egdes. After that, if you will do yourImage-newImage, you will get the inside pixels of the abject that are not edges.
I think it can make some of the the work, to further you to the solution.