I've written a program that creates a grid of hexagons, some black, some white. This is done randomly. I then choose randomly a subset of hexagons on the edges of which to place red diamonds. This script is designed to build pretend rock microstructures with grains (hexagons) and pore spaces (diamonds) for materials modeling. I'm using the fill() command to create each shape. The problem is that when I fill in the red diamonds, the edge of the hexagon beneath it is still showing through. I tried to post an image, but since this is my first time posting, it won't let me. I can email though, if anyone wants to see.
So to create the black hexagons:
h= fill(hexXY(i,j,1)+vx,hexXY(i,j,2)+vy,'k');
set(h,'edgecolor','k')
where the hexXY matrix holds x and y coordinates for the center of the hexagon, which added to the vx and vy arrays gives the vertices of each point on the hexagon. I then do the same thing with the diamonds:
h=fill(hexXY(i,j,1)+dvx,hexXY(i,j,2)+dvy,'r');
set(h,'edgecolor','r')
But, as I said, the black edges of the hexagons show through the red. I provided the vertices in order like you would draw them, though I don't think that should matter. I tried uistack and using patch, but neither worked for me. I can't set the hexagon edge color to none, because I have also have white hexagons, and if I set the background color to black I'd get black lines between the white hexagons. I removed have to remove the edge from either black or white hexagons, because where the two touch, the edges give messy pixelation.
Can anyone help me figure out how to get the red diamonds filled in properly?
EDIT: I didn't mention before, that this only occurs while saving the figure.You can't see it in the figure window. I've tried using print() and hgexport(), and changing the renderer, to no avail. Here is a small example with numbers pulled from my code to run:
hold on
v1=[0.3929 0.4107 0.3929 0.3571 0.3393 0.3571];
v2=[0.6907 0.6598 0.6288 0.6288 0.6598 0.6907];
h= fill(v1,v2,'k');
set(h,'edgecolor','k')
v3=[0.3750 0.3929 0.3750 0.3571 0.3750];
v4=[0.6366 0.6288 0.6211 0.6288 0.6366];
h=fill(v3,v4,'r');
set(h,'edgecolor','r')
set(gca,'position',[0 0 1 1],'units','normalized')
set(gcf,'PaperUnits','Inches','PaperPosition',[0 0 5 5]);
hgexport(gcf, 'test', hgexport('factorystyle'), 'Format', 'tiff','Resolution',600);
Here is the image saved with hgexport:
Try making your edges transparent:
set(h,'edgealpha',0)
Something weird is causing the original problem. If the commands are kept simple, everything appears fine:
h1= fill([1,2,3,3,2,1],[2,4,3,2,0,1],'m');
set(h1,'edgecolor','m')
hold on
h2= fill([2,3,2.5],[2,1,pi],'g');
set(h2,'edgecolor','g')
But the background edge moves forward when the foreground triangle is changed.
set(h2,'edgealpha',0) % an example of what can cause the problem to appear.
I don't know what's causing that.
If set(h,'edgealpha',0) does not work (as suggested by #user1739107), you may try set(h,'edgecolor','none').
On OSX R2012b, both solutions work fine.
Related
I have 4 coordinates assigned to variables, so I would just like to colour in the rectangle that is created from these variables. I tried the fill function, but I cant gather much information from the example.
When I try to use:
fill(bottom left point, top right point,'g')
the figure it makes only shows a line between those points, and doesn't colour in the entire area.
I'm using MATLAB R2019b, if that helps.
Also, if its possible to fill the rectangle with a pattern instead, please let me know aswell.
Thanks in advance
I have already tried imfill(img) but that doesn't work at all.
I have noticed that imfill works for this purpose only for images in which the object's boundary is complete and not broken like the image i am taking .
For this particular image do the following:
Prepend a white row to the image to close the contour.
Fill the contour.
Remove the helper row.
Anything else requires more information and examples.
Matlab documentation states that "a hole is a set of background pixels that cannot be reached by filling in the background from the edge of the image". In this case any pixel can be reached from the edge because its boundary is not complete. Therefore, technically there is no hole in the image you posted.
I am having trouble to change the bar color, I want it to be white in the middle, and red at the edge. Looking at matlab's description
if I do:
bar(y,'FaceColor','w','EdgeColor','r','LineWidth',1)
It should give me the above. However, when I actually run it, it only give me white graph.
Update: my y is:
y=zeros(1,5000); y(3000)=1; y(4000)=1;
Using the above, I got....
With so many bars, Matlab probably has trouble differentiating edge ('EdgeColor') and fill ('FaceColor') of each. After all, each complete bar is less than a screen pixel.
I suggest you use white edge and colored fill. That works for me. It's as if 'FaceColor' had precedence over 'EdgeColor'.
bar(y,'FaceColor','r','EdgeColor','w','LineWidth',1)
Or better yet: replace each bar by a line, that is, use stem:
stem(y,'r','marker','none')
I have scanned copies of currency notes from which I need to extract only the rectangular notes.
Although the scanned copies have a very blank background, the note itself can be rotated or aligned correctly. I'm using matlab.
Example input:
Example output:
I have tried using thresholding and canny/sobel edge detection to no avail.
I also tried the solution given here but it detects the entire image for cropping and it would not work for rotated images.
PS: My primary objective is to determine the denomination of the currency. There are a couple of methods I thought I could use:
Color based, since all currency notes have varying primary colors.
The advantage of this method is that it's independent of the
rotation or scale of the input image.
Detect the small black triangle on the lower left corner of the note. This shape is unique
for each denomination.
Calculating the difference between 2 images. Since this is a small project, all input images will be of the same dpi and resolution and hence, once aligned, the difference between the input and the true images can give a rough estimate.
Which method do you think is the most viable?
It seems you are further advanced than you looked (seeing you comments) which is good! Im going to show you more or less the way you can go to solve you problem, however im not posting the whole code, just the important parts.
You have an image quite cropped and segmented. First you need to ensure that your image is without holes. So fill them!
Iinv=I==0; % you want 1 in money, 0 in not-money;
Ifill=imfill(Iinv,8,'holes'); % Fill holes
After that, you want to get only the boundary of the image:
Iedge=edge(Ifill);
And in the end you want to get the corners of that square:
C=corner(Iedge);
Now that you have 4 corners, you should be able to know the angle of this rotated "square". Once you get it do:
Irotate=imrotate(Icroped,angle);
Once here you may want to crop it again to end up just with the money! (aaah money always as an objective!)
Hope this helps!
This is the original image.
I changed it into 1) grayscale and apply 2) threshold.
As seen in the original image, there are some shadow that still exist after apply two method above.
But most of the image are perfect after 2 method.
I need to extract the text, so I need to get rid of the noise. I almost finish the work but the problem is some cases have a black border and I wanted to replace that into white color.
And I insist that I want just only border to turn into white
I think of create some white rectangle and fill the border with those rectangle but I don't know how to do it.
How can I achieve that using Matlab?
Any other method would be appreciate too!
If you can be sure only the borders will be black, why not simply crop the image until all isolated shapes are recognizable characters? Something along the lines of
done = false;
ii = 1;
while (~done)
% fill the outer border
img(:,ii) = 255; img(ii,:) = 255;
img(:,end-ii+1) = 255; img(end-ii+1,:) = 255;
% (run your algorithms here. It positive match, done = true)
end
That could be computationally intensive, since you have to do pattern recognition on each iteration, but you indicated it only occurs in "some cases".
Otherwise, I suspect some morphological operation can also be used, probably erosion or thinning or similar. But that has the drawback of altering the characters you want to match. But, if all images you have to process look like the one you show, I hardly suspect that'll give you any problems.
Some ways to detecting straight lines are mentioned in this question. I'd say you could detect all lines, and remove those (with a small tolerance around it) that are perfectly horizontal/vertical and on one of the edges.