i need to build a function that can set in which part the big circle belong to (top , bottom, undermined),
the minimum size of the circle is 3x3.
black color = 1
white color = 0
for example:
https://serving.photos.photobox.com/17525810496b857f6fc6a1bd5b21ad9fba80f1e6c878dc45d05764a04f861e026fb52115.jpg "example images"
i thought to split my image to half
(image[0:len(image)/2] and image[len(image)/2:]) ( the numbers of row is even)
and find a way to looking for array inside array, ( a minimum of 3x3) to find solution to this problem, but i dunno how to realize it.
Related
I am trying to segment the blue components from a set of images. In most images where blue components have a large spread, otsu thresholded image works properly well. However, for images where blue components are minimal, the results are not ok and seems to include the non-relevant sections. Example below:
Are there ways to improve the otsu thresholding such that only relevant parts are segmented but not necessarily making the other images suffer?
I already tried global and adaptive thresholding but otsu particularly captured betters which however included unnecessary details.
Here's the code:
l_image = remove_background(image)
l_image = cv2.cvtColor(l_image, cv2.COLOR_BGR2GRAY)
ret1,th1 = cv2.threshold(l_image,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
mask = (th1 != 255)
sel = np.ones_like(image)
sel[mask] = image[mask]
sel = cv2.cvtColor(sel, cv2.COLOR_HSV2BGR)
#we simply set these channels to 0 to remove excess background
sel[:,:,1] = 0
sel[:,:,2] = 0
Here's the sample image.
The main issue with the logic in your code is that you are looking for something that is distinguished primarily by color, but throw away the color information first by converting the image to grayscale.
Instead, consider looking at color properties of each pixel. One easy way to do so is to look at the HCV color space. This is a similar color space to the more common HSV, with "C" for chroma instead of "S" for saturation, where S = C / V. I'm suggesting this because it's so easy to compute the "C" channel, which is the one that would have most of the contrast in this image. Note that all the complexity is in computing "H", the hue, and that would be ideally used to find a specific color independently of its brightness, but that requires a double threshold on the "H" channel plus a threshold on the "S" channel. For this simple case, a single threshold on the "S" channel is sufficient to find the colored regions: we have only blue, we don't care about what color it is, we just want to find the color.
To compute the "C" (chroma) channel, we find the difference between the largest and the smallest of the RGB values (for each pixel independently):
rgbmax = np.amax(image, axis=2)
rgbmin = np.amin(image, axis=2)
c = rgbmax - rgbmin
As you can guess, a simple threshold of this image leads to finding the colored regions. The green background can easily be subtracted before processing, or after.
Edit: after #Cris Luengo comment, the green channel works better than the blue one.
You can apply Otsu's threshold on the green channel (of BGR).
Results are not perfect but much better.
img = img[:,:,1] #get the green channel
th, img = cv2.threshold(img, 0, 255, cv2.THRESH_OTSU)
output:
I'm using a CIPerspectiveTransformWithExtent filter to apply homographies (perspective warp) to images on OS X. So far, so good, and I can get the desired warping applied to my images.
I'm still struggling however with the border behavior. I would like the output of the filter to be clipped outside the original image domain:
I managed to do it for the lower and left borders by shifting the origin of the inputExtent rectangle of the correct amount. For example, if the lower left corner is projected to x = -10 then using extent.origin.x = 10 will correctly clip the left border;
on the other hand, the upper and right borders are always shown in the output image. For example, if the rightmost corner is projected to x = width + 10, setting the extent via extent.origin.x = 0, extent.size.width = width; does not work an the rightmost corner remains visible.
Am I doing anything wrong here? or maybe I'm not trying the right way to achieve my goal?
I have a set of m non-rotated, integer (pixel) aligned rectangles, each of which may or may not overlap. The rectangles cover thousands of pixels. I need to find the minimum sized bounding box that covers all areas that are covered by n of the m rectangles.
A (dirty) way of doing this is to paint a canvas that covers the area of all the targets. This is O(mk) where m is the number of rectangles and k is the number of pixels per rectangle. However since k is much greater than m I think there is a better solution out there.
This feels like a dynamic programming problem...but I am having trouble figuring out the recursion.
Solution which is better but still not great:
Sort the start and end points of all the rectangles in the X direction O(mlogm), iterate and find the x positions that may have over n rectangles, O(m) loop. For each x position that may have over n rectangles, take the rectangles at that position and sort the starts and stops at that position (O(mlogm)). Find the region of overlap, keep track of the bounds that way. Overall, O(m^2logm).
Hello MadScienceDreams,
Just to clarify, the bounding box is also non-rotated, correct?
If this is the case, then just keep track of the four variables: minX, maxX, minY, maxY–representing left-most, right-most, top-most, and bottom-most pixels–that define the bounding box, loop through each of the rectangles updating the four variables, and defining the new bounding box given those four variables.
EDIT
It looks like you are asking about finding the bounds of some subset of rectangles, not the whole set.
So you have M rectangles, and you choose N rectangles from them, and find the bounds within that.
Even in this situation, looping through the N rectangles and keeping track of their bound would be at most O(m), which isn't bad at all.
I feel that I must be misunderstanding your question since this response isn't what you are probably looking for; is your question actually trying to ask how to precompute the bounds so that given any subset, know the total bounds in constant time?
Is this defines your question? For bounding box => #rect_label >= n
How about we starts with one box and find the next box that has nearest furthest corner from it. Now we have a region with two box. Recursively find the next region, until we have n boxes.
While we need to start on every box, we only need to actively work on the currently smallest regions. The effect is we start from the smallest cluster of boxes and expand out from there.
If n is closer to m than 0, we can reverse the search tree so that we start from the omni-all-enclosing box, chopping off each bordering box to create the next search level. Assuming we only actively work on the smallest remaining region, effect is we chop off the emptiest region first.
Is it too complicated? Sorry I can't remember the name of this search. I'm not good at maths, so I'll skip the O notation. >_<
I propose the following algorithm :
prepareData();
if (findBorder('left')) {
foreach (direction in ['top', 'right', 'bottom']) {
findBorder(direction)
}
} else noIntersectionExists
prepareData (O(mlogm)):
Order vertical bounds and horizontal bounds
Save the result as:
- two arrays that point to the rectangle (arrX and arrY)
- save the index as a property of the rectangle (rectangle.leftIndex, rectangle.topIndex, etc.
findBorder(left): // the other direction are similar
best case O(n), worst case O(2m-n)
arrIntersections = new Array;
//an intersection has a depth (number of rectangles intersected), a top and bottom border and list of rectangles
for(i=0; i < 2*m-n-1; i++){ // or (i = 2*m-1; i > n; i--)
if(isLeftBorder(arrX[i])){
addToIntersections(arrX[i].rectangle, direction);
if(max(intersections.depth) = n) break;
} else {
removeFromIntersections(arrX[i].rectangle, direction);
}
}
addToIntersections(rectangle, direction): // explanations for direction=left
Best case: O(n), worst case: O(m)
hasIntersected = false;
foreach(intersection in intersection){
if(intersect(intersection, rectangle)){
hasIntersected = true
intersections[] = {
depth: intersection.depth,
bottom: min(intersection.bottom, rectangle.bottom),
top: max(...)}
intersection.depth++
intersection.bottom = max(intersection.bottom, rectangle.bottom)
intersection.top = max(...)
}
}
if(!hasIntersected)
intersections[]={depth:1, bottom:rectangle.bottom, top:rectangle.top}
This gives an overall order between O(n^2) and O(m*(m-n/2))
I hope my pseudo code is clear enough
please , see following image, here you can see blue rectangle is custom shape bounds and custom shape is shoe , i want to find area of a portion written in image and i want that area in form of rectangle
do is there any path iterator concept ?
Note
custom shape i derived from image of the same size.
I would do it like this:
1.create table for all bounding box-rect perimeter lines
each value in it will represent the empty space length form border line to shape
something like this:
the values are found by simple image scanning until first non space color found
2.now bruteforce find the biggest rectangle area
x,y = top left corner
for xs = 1 to bounding box width
now scan the max valid height of rectangle from x to x + xs (x grows to the right)
// it should be the min y0[x..x+xs]
remember the biggest valid area/size combination
do this for all 4 combinations (star from the other corners)
I now Brute-force is slow but
you can divide perimeter lines not by pixels but with some step instead
also I am sure this can be optimized somehow
for example by derivation of perimeter find the extremes and check from them backwards
when the size will start shrinking then stop ...
of course take in mind that on complicated shapes this optimization will not work ...
My dataset consists of three vectors (x,y and z). I plot these values as dots in a 3d-plot with plot3(x,y,z), which is fine. I also want to show a plane in the same plot. To get the data of this plot I use linear regression on x and y to get a new z.
This is how it looks:
(source: bildr.no)
I want the surf to be filled with only one color (say light blue or gray) and set the opacity, to make it see-through. How can I do this?
The easiest way to create a surface that has just 1 color and a given transparency value is to set the 'FaceColor' and 'FaceAlpha' properties of the surface object:
hSurface = surf(...your arguments to create the surface object...);
set(hSurface,'FaceColor',[1 0 0],'FaceAlpha',0.5);
This example sets the surface color to be red and the transparency to 0.5. You can also set the edge properties too (with 'EdgeColor' and 'EdgeAlpha').
It is not clear to me what you want to do. When you say one color for the surf, do you mean exactly one color, or do you mean you want shades of gray?
Here is some code that will do a variety of things, you can choose which lines to use:
x = rand(1,20);
y = rand(1,20);
z = rand(1,20);
[X,Y] = meshgrid(linspace(0,1,10),linspace(0,1,10));
Z = rand(10)*0.1;
clf
plot3(x,y,z,'.');
hold on
h = surf(X,Y,Z)
hold off
%% This will change the color
colormap(copper)
%% This will remove colordata
set(h, 'cdata',zeros(10))
%% This will make transparent
alpha(0.5)
Completing the answer from gnovice, an extra ingredient in set(hsurface...) may be required (Matlab R2010b 64):
hSurface = surf(...your arguments to create the surface object...);
set(hSurface, 'FaceColor',[1 0 0], 'FaceAlpha',0.5, 'EdgeAlpha', 0);
to make invisible the point-to-point edges of the plotted surface
#matlabDoug has what you need, I think. The property cdata holds color data that gets a color map applied to it. Setting it to an array the same size as your surface data, with each element in that array having the same value, will make your surface one color. With the default color map, setting everything in cdata to zero will make your surface blue, and setting everything to 1 will make the surface red. Then you can play with the alpha to make it transparent.