MATLAB: Plotting lines inside an RGB Cube - matlab

I'm a MATLAB newbie and while I've found a few ways to create and show a RGB cube, I haven't figured out how to plot something within it.
Here's some context: I've got a few approaches to colour cycling implemented in javascript/html5. Concretely, my first attempt naively interpolates between provided "endpoints" in the RGB-colour space, another approach performs a similar translation in HSV-colour space.
What I'd like to do is gain some geometric intuition as to what my different models of colour cycling actually look like if I were to plot out the transitions in an RGB-cube. So to that end, I need to do the following:
1. Create a RGB Cube (I can already do this by cutting/pasting a solution that uses patch() that was found here
2. Plot my colour cycling models inside a semi-translucent RGB Cube from 1
Would appreciate any help on this!

Related

Find the other end of a curve after a cut in an image

I would like to follow a curve (with matlab or opencv) and to find the other end of it when it is cut by an empty space like this example, which is simplified to illustrate the problem:
Link to image of cut curve
Real images are more like this one: Link to real image to analyse
To follow the curve, I can use a skeleton and look at the neighbourhood. The problem is that I don't know how to find the other end efficiently.
I don't think that closing or opening operations could help because as shown on the previous image, there are other curves and the two parts of the curve are quite far from each other so it could lead to boundaries between the different curves instead of the two parts.
I was thinking about polynomial evaluation which could be a solution for simple curves but I am not sure about the precision I could get. If I use a skeleton, I have to find exactly the right pixel or to search in a reasonable neighbourhood which would take some time and once again, as there are other curves in the images, I have to be sure that I will find the good one.
That's why I am searching for an existing function which could estimate precisely the trajectory of the curve and give an usefull output to go further and find the second part of the curve.
If that kind of function doesn't exist, I'm open to any other way of analysing the problem if it can help.
I will start to explain with the first image you provided, you can implement common OpenCV function useful for detecting contour(black region in your case as you have binary image) known as cv2.findContours(), which returns the coordinates of the edges of the surface detected then you can plot each detected contour separately in a blank image to get the edge of your desired line.
Now coming to your 2nd image you have to be slightly careful while performing above analysis as there are many tiny lines. get back to me for further help

MATLAB: Digitizing a plot with multiple variables and implementing the data

I have 8 plots which I want to implement in my Matlab code. These plots originate from several research papers, hence, I need to digitize them first in order to be able to use them.
An example of a plot is shown below:
This is basically a surface plot with three different variables. I know how to digitize a regular plot with just X and Y coordinates. However, how would one digitize a graph like this? I am quite unsure, hence, the question.
Also, If I would be able to obtain the data from this plot. How would you be able to utilize it in your code? Maybe with some interpolation and extrapolation between the given data points?
Any tips regarding this topic are welcome.
Thanks in advance
Here is what I would suggest:
Read the image in Matlab using imread.
Manually find the pixel position of the left bottom corner and the upper right corner
Using these pixels values and the real numerical value, it is simple to determine the x and y value of every pixel. I suggest you use meshgrid.
Knowing that the curves are in black, then remove every non-black pixel from the image, which leaves you only with the curves and the numbers.
Then use the function bwareaopen to remove the small objects (the numbers). Don't forget to invert the image to remove the black instead of the white.
Finally, by using point #3 and the result of point #6, you can manually extract the data of the graph. It won't be easy, but it will be feasible.
You will need the data for the three variables in order to create a plot in Matlab, which you can get either from the previous research or by estimating and interpolating values from the plot. Once you get the data though, there are two functions that you can use to make surface plots, surface and surf, surf is pretty much the same as surface but includes shading.
For interpolation and extrapolation it sounds like you might want to check out 2D interpolation, interp2. The interp2 function can also do extrapolation as well.
You should read the documentation for these functions and then post back with specific problems if you have any.

Constructing voxels of a 3D cube in MATLAB

I want to construct a 3D cube in MATLAB. I know that the units of any 3D shape are voxels not pixels. Here is what I want to do,
First, I want to construct a cube with some given dimensions x, y, and z.
Second, according to what I understand from different image processing tutorials, this cube must consists of voxels (3D pixels). I want to give every voxel an initial color value, say gray.
Third, I want to access every voxel and change its color, but I want to distinguish the voxels that represent the faces of the cube from those that represent the internal region. I want to axis every voxel by its position x,y, z. At the end, we will end up with a cube that have different colors regions.
I've searched a lot but couldn't find a good way to implement that, but the code given here seems very close in regard to constructing the internal region of the cube,
http://www.mathworks.com/matlabcentral/fileexchange/3280-voxel
But it's not clear to me how it performs the process.
Can anyone tell me how to build such a cube in MATLAB?
Thanks.
You want to plot voxels! Good! Lets see how we can do this stuff.
First of all: yeah, the unit of 3D shapes may be voxels, but they don't need to be. You can plot an sphere in 3D without it being "blocky", thus you dont need to describe it in term of voxels, the same way you don't need to describe a sinusoidal wave in term of pixels to be able to plot it on screen. Look at the figure below. (same happens for cubes)
If you are interested in drawing voxels, I generally would recommend you to use vol3D v2 from Matlab's FEX. Why that instead of your own?
Because the best (only?) way of plotting voxels is actually plotting flat square surfaces, 6 for each cube (see answer here for function that does that). This flat surfaces will also create some artifacts for something called z-fighting in computer graphics. vol3D actually only plots 3 surfaces, the ones looking at you, saving half of the computational time, and avoiding ugly plotting artifacts. It is easy to use, you can define colors per voxel and also the alpha (transparency) of each of them, allowing you to see inside.
Example of use:
% numbers are arbitrary
cube=zeros(11,11,11);
cube(3:9,3:9,3:9)=5; % Create a cube inside the region
% Boring: faces of the cube are a different color.
cube(3:9,3:9,3)=2;
cube(3:9,3:9,9)=2;
cube(3:9,3,3:9)=2;
cube(3:9,9,3:9)=2;
cube(3,3:9,3:9)=2;
cube(9,3:9,3:9)=2;
vold3d('Cdata',cube,'alpha',cube/5)
But yeah, that still looks bad. Because if you want to see the inside, voxel plotting is not the best option. Alphas of different faces stack one on top of the other and the only way of solving this is writing advanced computer graphics ray tracing algorithms, and trust me, that's a long and tough road to take.
Very often one has 4D data, thus data that contains 3D location and a single data for each of the locations. One may think that in this case, you really want voxels, as each of them have a 3D +color, 4D data. Indeed! you can do it with voxels, but sometimes its better to describe it in some other ways. As an example, lets see this person who wanted to highlight a region in his/hers 4D space (link). To see a bigger list I suggest you look at my answer in here about 4D visualization techniques.
Lets try wits a different approach than the voxel one. Lets use the previous cube and create isosurfaces whenever the 4D data changes of value.
iso1=isosurface(cube,1);
iso2=isosurface(cube,4);
p1=patch(iso1,'facecolor','r','facealpha',0.3,'linestyle','none');
p2=patch(iso2,'facecolor','g','facealpha',1,'linestyle','none');
% below here is code for it to look "fancy"
isonormals(cube,p1)
view(3);
axis tight
axis equal
axis off
camlight
lighting gouraud
And this one looks way better, in my opinion.
Choose freely and good plotting!

Corner Detection in 2D Vector Data

I am trying to detect corners (x/y coordinates) in 2D scatter vectors of data.
The data is from a laser rangefinder and our current platform uses Matlab (though standalone programs/libs are an option, but the Nav/Control code is on Matlab so it must have an interface).
Corner detection is part of a SLAM algorithm and the corners will serve as the landmarks.
I am also looking to achieve something close to 100Hz in terms of speed if possible (I know its Matlab, but my data set is pretty small.)
Sample Data:
[Blue is the raw data, red is what I need to detect. (This view is effectively top down.)]
[Actual vector data from above shots]
Thus far I've tried many different approaches, some more successful than others.
I've never formally studied machine vision of any kind.
My first approach was a homebrew least squares line fitter, that would split lines in half resurivly until they met some r^2 value and then try to merge ones with similar slope/intercepts. It would then calculate the intersections of these lines. It wasn't very good, but did work around 70% of the time with decent accuracy, though it had some bad issues with missing certain features completely.
My current approach uses the clusterdata function to segment my data based on mahalanobis distance, and then does basically the same thing (least squares line fitting / merging). It works ok, but I'm assuming there are better methods.
[Source Code to Current Method] [cnrs, dat, ~, ~] = CornerDetect(data, 4, 1) using the above data will produce the locations I am getting.
I do not need to write this from scratch, it just seemed like most of the higher-class methods are meant for 2D images or 3D point clouds, not 2D scatter data. I've read a lot about Hough transforms and all sorts of data clustering methods (k-Means etc). I also tried a few canned line detectors without much success. I tried to play around with Line Segment Detector but it needs a greyscale image as an input and I figured it would be prohibitivly slow to convert my vector into a full 2D image to feed it into something like LSD.
Any help is greatly appreciated!
I'd approach it as a problem of finding extrema of curvature that are stable at multiple scales - and the split-and-merge method you have tried with lines hints at that.
You could use harris corner detector for detecting corners.

5-dimensional plotting in matlab for classification

I want to create a 5 dimensional plotting in matlab. I have two files in my workspace. one is data(150*4). In this file, I have 150 data and each has 4 features. Since I want to classify them, I have another file called "labels" (150*1) that includes a label for each data in data files. In other words the label are the class of data and I have 3 class: 1,2,3
I want to plot this classification, but i can't...
Naris
You need to think about what kind of plot you want to see. 5 dimensions are difficult to visualize, unless of course, your hyper-dimensional monitor is working. Mine never came back from the repair shop. (That should teach me for sending it out.)
Seriously, 5 dimensional data really can be difficult to visualize. The usual solution is to plot points in a 2-d space (the screen coordinates of a figure, for example. This is what plot essentially does.) Then use various attributes of the points plotted to show the other three dimensions. This is what Chernoff faces do for you. If you have the stats toolbox, then it looks like glyphplot will help you out. Or you can plot in 3-d, then use two attributes to show the other two dimensions.
Another idea is to plot points in 2-d to show two of the dimensions, then use color to indicate the other three dimensions. Thus, the RGB assigned to that marker will be defined by the other three dimensions. Of course, that means you must be able to visualize what the RGB coordinates of a color represent, so you need to understand color as it is represented in an RGB space.
You can use scatter3 to plot your data, using three features of data as dimensions, the fourth as color, and the class as different markers
figure,hold on
markerList = 'o*+';
for iClass = 1:nClasses
classIdx = dataClass==iClass;
scatter3(data(classIdx,1),data(classIdx,2),data(classIdx,3),[],data(classIdx,4),...
'marker',markerList(iClass));
end
When you use color to represent one of the features, I suggest to use a good colormap, such as pmkmp from the Matlab File Exchange instead of the default jet.
Alternatively, you can use e.g. mdscale to transform your higher-dimensional data to 2D for standard plotting.
There's a model called SOM (Self-organizing Maps) which builds a 2-D image of a multidimensional space.