I create a polygon on image_area in matlab.
I used impoly.
But after creation polygon.
I need to block possibility to move and drag impoly (ROI is already created).
I don't know how I should do it ?
I would appreciate for any help please.
You can set the makeConstrainToRectFcn such that it is a rectangle encompassing your ROI, then whenever you try to move the latter it won't work. You can also, after creating the ROI, set the setVerticesDraggable method to false in order to prevent vertices from being dragged.
Sample code (adapted from example by the Mathworks):
clc
clear
figure
imshow('gantrycrane.png');
h = impoly(gca, [188,30; 189,142; 93,141; 13,41; 14,29]);
%// Get currentposition
Pos = getPosition(h);
%// Prevent draggable vertices
setVerticesDraggable(h,0);
%// Set up rectangle to prvent movement of ROI
fcn = makeConstrainToRectFcn('impoly', [min(Pos(:,1)) max(Pos(:,1))], [min(Pos(:,2)) max(Pos(:,2))]);
%// Apply function
h.setPositionConstraintFcn(fcn);
which results in this kind of situation (with red rectangle for illustration):
Related
I try to determine the coordinates of a puzzle piece on the original image using the normxcorr2 function. Then I draw a rectangle on the correspondence of the two elements. Unfortunately, I notice that the coordinates that this match has given me are not good. Could someone have an idea how to improve the use of this feature and get some better results.
The puzzle piece has the name "cpiece" and the original picture has the name "bild"
clear all;
close all;
clc
cpiece = im2gray(imread('cpiece1.jpg'));
bild = im2gray(imread('original.jpg'));
figure(1)
montage({bild,cpiece})
c = normxcorr2(cpiece,bild);
figure(2)
surf(c)
shading flat
[ypeak,xpeak] = find(c==max(c(:)));
yoffSet = ypeak-size(cpiece,1);
xoffSet = xpeak-size(cpiece,2);
figure(3)
imshow(bild)
drawrectangle(gca,'Position',[xoffSet,yoffSet,size(cpiece,2),size(cpiece,1)],'FaceAlpha',0);
It seems, the problem returns back to the quality of your template image, And Check if the scales between original image and the template are exactly the same
I've got a row dimensional array of values that I want to visualize in 3D and I'm using scene kit under OS X for it. I've done it in a clumsy manner by using each column as a point on the X axis, each row as a point on the Z axis, and each value as a normalized point on the Y axis -- I place a sphere at the vector defined by each data point. It works but it doesn't look too good.
I've also done this by building a mesh of lines based on #Matthew's function in Drawing a line between two points using SceneKit (the answer he posted, not the original question). For each point I use his function to draw two lines - one between my current point and the next point to the right and another between my current point and the next point towards the front (except when there is no additional column/row, of course).
Using the second method, my results look much better... however the performance is quite hideous! It takes quite a long time to complete the initial rendering, and if I use a trackpad/mouse to rotate or translate the scene, I might as well get a cup of coffee to wait until my system is usable again (and this is not much hyperbole). Using the sphere method, things render and update very quickly.
Any advice on how to improve the performance when using the lines method? (Note that I am not trying to add both lines and spheres at the same time.) Code-wise, the only difference between approach is which of the following methods gets called (and that for each point, addPixelAt... is called once, but addLineAt... is called twice for most points).
- (SCNNode *)addPixelAtRow:(CGFloat)row Column:(CGFloat)column size:(CGFloat)size color:(NSColor *)color
{
CGFloat radius = 0.5;
SCNSphere *ball = [SCNSphere sphereWithRadius:radius*1.5];
SCNMaterial *material = [SCNMaterial material];
[[material diffuse] setContents:color];
[[material specular] setContents:color];
[ball setMaterials:#[material]];
SCNNode *ballNode = [SCNNode nodeWithGeometry:ball];
[ballNode setPosition:SCNVector3Make(column, size, row)];
[_baseNode addChildNode:ballNode];
return ballNode;
}
- (SCNNode *)addLineFromRow:(CGFloat)row1 Column:(CGFloat)column1 size:(CGFloat)size1
toRow2:(CGFloat)row2 Column2:(CGFloat)column2 size2:(CGFloat)size2 color:(NSColor *)color
{
SCNVector3 positions[] = {
SCNVector3Make(column1, size1, row1),
SCNVector3Make(column2, size2, row2)
};
int indices[] = {0, 1};
SCNGeometrySource *vertexSource = [SCNGeometrySource geometrySourceWithVertices:positions count:2];
NSData *indexData = [NSData dataWithBytes:indices length:sizeof(indices)];
SCNGeometryElement *element = [SCNGeometryElement geometryElementWithData:indexData
primitiveType:SCNGeometryPrimitiveTypeLine
primitiveCount:1
bytesPerIndex:sizeof(int)];
SCNGeometry *line = [SCNGeometry geometryWithSources:#[vertexSource] elements:#[element]];
SCNMaterial *material = [SCNMaterial material];
[[material diffuse] setContents:color];
[[material specular] setContents:color];
[line setMaterials:#[material]];
SCNNode *lineNode = [SCNNode nodeWithGeometry:line];
[_baseNode addChildNode:lineNode];
return lineNode;
}
From the data that you've shown in your question I would say that your main problem is the number of draw calls. Your's is in the tens of thousands, which is way too much. It should probably be a lot closer to ~100.
The reason why you have so many draw calls is that you have so many distinct objects in your scene (each line). The better (but more advanced solution) would probably be to generate a single element for the entire mesh that consists of all the lines. If you want to achieve the same rendering with that mesh (with a color from cold to warm based on the height) then you could do that in a shader modifier.
However, in your case I would start by flattening all the lines (since that would be the smallest code change and should still have a significant performance improvement in your case).
(Optimizing performance is always an iterative process. Once you fix one thing there will be another thing which is the most expensive operation. Without your code I can only say what would help with the current performance problem)
Create an empty node (without adding it to your scene) and generate all the lines, adding them to this node. Then create a flattened copy of that node by calling flattenedClone on the node that contains all the lines
SCNNode *nodeWithAllTheLines = [SCNNode node];
// create all the lines and add them to it...
SCNNode *flattenedNode = [nodeWithAllTheLines flattenedClone];
[_baseNode addChildNode:flattenedNode];
When you do this you should see a significant drop in the number of draw calls (the number after the diamond in the statistics) and hopefully a big increase in performance.
In my image I have 5 Objects in black-white form. Some are respectively small, some are bigger.
So what i am trying to do is drawing a BoundingBox or tag the objects which has less area than others (ex. under 10pixels/area) .
I couldn't make this happen, can anyone help?
That's two separate problems. The first is to select only objects above a certain area. So simply remove all objects below it:
clean = bwareaopen (im, 10); # remove all objects with area below 10
Then for the second problem there are many possibilities. You can get their borders:
borders = bwperim (clean);
imshow (borders);
You can label them:
labeled = bwlabel (clean);
imshow (labeled);
Or you can get their bounding box (which depending on the shape of your objects may overlap):
props = regionprops (clean, 'BoundingBox');
all_bb = props.BoundingBox;
boxes = false (size (clean));
for i = 1:numel (all_bb)
bb = all_bb{i};
bb(round (bb(2):bb(2)+bb(4), bb(1):bb(1)+bb(3))) = true;
end
imshow (boxes);
Note: this was written out of my head, no testing. There may be small oversights, but nothing major.
I want to get only leaf from an image.
The background is a normal white paper(A4) and there is some shadow.
I apply some method (structure element,edge detection using filter) but I cannot find the general way which can apply all the image.
these are examples.
Are there better methods for this problem??
thank you
another example.
and the result I got is
By using
hsv_I = rgb2hsv(I);
Is = hsv_I(:,:,2);
Is_d = imdilate(Is,strel('diamond',4));
Is_e = imerode(Is,strel('diamond',2));
Is_de = imerode(Is_d,strel('disk',2));
Is_def = imfill(Is_de,'holes');
Is_defe = imerode(Is_def,strel('disk',5));
Then Is_defe is a mask to segment
But the method that i did is very specific. I cannot use this in general.
If you have the Image Processing Toolbox, you could do as follows:
The code below first estimates the threshold with the function graythresh, thresholds the image and fills holes with the imfill function. Suppose I is a cell containing your RGB images:
for k=1:length(I)
t=graythresh(rgb2gray(I{k}));
BW{k}=imfill(~im2bw(I{k}, t), 'holes');
subplot(length(I),1,k), imshow(BW{k});
end
I want develop an matlab's application that can show the bounding box to the object in the image.
I have detected the object, and cropped it.
And now, for the boundng box, i just have to add 10 in all my pixel.
For exmpl:
x=x+10;
y=y+10;
w=w+10;
h=h+10;
I use imcrop function.
But the problem is that i dont understand how to get the pixel's coordinates from imcrop.
[I_crop, I_rect]=imcrop(ImSeq(:,:,1),[])
I_rect=floor(I_rect);
final_rect=I_rect;
for t=1:NumImages
cur_r=final_rect(2);
cur_c=final_rect(1);
for r= cur_r -10:cur_r+10
for c=cur_c-10:cur_c+10
temp= abs(I_crop-ImSeq(r:r+I_rect(4),c:c+I_rect(3),t));
what is final_rect(2), final_rect(1), I_rect(4) and I_rect(3)?
How i can get the coordinates of x,y,w,h of the cropped image??
Thanks
In [I2 rect] = imcrop(I), rect is the cropping rectangle, a four-element position vector. Within the original image, the cropped area is defined by:
rect(2) the current row
rect(1) the current column
rect(3) is the width
rect(4) the height.