How to extract a 2D array from an image of the same array? - arrays

Is it possible to extract a 2D matrix from an image of the same? Having no related experience in this area, I am having trouble proceeding further.
For example, if the image of the array is this, the corresponding 2D array(with blanks denoted by 0) would be as follows:
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 0 0 0
0 9 8 0 0 0 0 6 0
8 0 0 0 6 0 0 0 3
4 0 0 8 0 3 0 0 1
7 0 0 0 2 0 0 0 6
0 6 0 0 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9
I would like to know some algorithm or software that would help me extract the array. As I have no prior experience, even a push in the right direction would be appreciated.
Background: I was working on a basic Sudoku solver using Java, and I have implemented the same with a basic backtracking algorithm. Now, instead of giving the input manually by typing out the 2D array, I want to obtain the same from an image of the array.

Image recognition is not as simple as it appear to be. A low quality picture of low resolution with shadows or with shiny parts brighter than the rest is hard to deal with. Let alone that 3D angle of the camera and 2D rotations in the image plane. All those factors should be diminished or eliminated before image recognition even start.
Assuming you have a clean input image with known width and height what you need is to chop the input image in several squares corresponding to matrix entries. Then for each small subimage run a number recognition algorithm.
For the first part, many times it is better to transform the image from 24bits rgb colors to 8-bits grayscale. In that way image pixels with almost the same color in rgb space will be clustered to have the same intensity in the 8bit grayscale space. Even binary image with only two intensities would be useful in this case. There are image treatment packages that can do it for you. Then chopping the image is not harder than doing 2D array manipulation.
For the second part you can discard all squares with same intensity as empty. For the nonempty squares you have to call a number recognition algorithm.
You can use many packages for pattern recognition out there such as OpenCV or specific OCR (optical character recognition) packages.
It is not hard to write your own feedforward neural network for that:
https://en.m.wikipedia.org/wiki/Feedforward_neural_network
See also:
Recognize numbers in images

Related

How can I represent a symmetric matrix in CSR format?

Although I'm using C, the programming language and the code are irrelevant, I believe.
I want to represent a symmetric matrix in CSR format, for fast matrix-vector product.
The input stream I read from gives the upper-triangular part of the matrix only, number by number, left to right, row to row.
Example:
0 2 3 5
2 0 1 4
3 1 0 9
5 4 9 0
Input stream:
0 2 3 5 0 1 4 0 9 0
If I were to build a regular matrix from, say, two-dimensional array, it would be easy. All I need is the data I get. That's not the case for a CSR representation.
All I had to do was transpose the matrix in CSR. That way, the matrix-vector product is still efficient and easy to implement.
Building the transpose costs a lot of time, and also doubles the memory usage.
That's the best idea I could have. I appreciate any other.

Visualize a three-dimensional array like cubic lattice using MATLAB

I want to visualize a three-dimensional array just like cubic lattice using MATLAB.
I have read How to plot 3D grid (cube) in Matlab, and Simple cubic lattice using three-dimensional array
If element in the array is only 0 and 1, I know how to use a three-dimensional array to draw a simple cubic lattice, the small cube has the same size.
However, Now I have a three-dimensional array like this,
cube(:,:,1) =
1 0 1
0 1 1
2 1 0
cube(:,:,2) =
0 0 1
1 5 1
0 1 0
cube(:,:,3) =
1 1 1
0 1 1
2 0 1
The array cube have value except 0 and 1. I want to visualize the array like cubic lattice, in which cube(:,:,1) denotes the first floor of the cubic lattice,
cube(:,:,2) denotes the second floor, and
cube(:,:,3) the third floor.
The value 0 denotes nothing, while value 1 denotes a small blue cube.
Value greater than 1 denotes sphere, the diameter of sphere varies according to the value.
The desired result is something like this:
Visualization of a three-dimensional array, 1 denotes a small green
cube,0 denotes nothing,Value greater than 1 denotes white sphere, the
diameter of sphere varies according to the value.
To explain my question more clear, show one visualization of two-dimensional array
1 denotes a small black sphere,0 denotes nothing,Value greater than 1
denotes white sphere, the diameter of sphere varies according to the
value.
The desired effect drawing
it is Ok, when side length of cube is 1
when set side length as 2, drawCube([ix,iy,iz],2,Royal_Blue). The problem occurs, cubes is overlapping,
Let me show you my attempt. It is based into drawing each cube and circle independently. This will be slow in if A is big.
Result:
The code should be self explanatory.
% Create some data. This piece of code just creates some matrix A with
% some 1s and 0s and inserts a 2 and a 3 to specific positions. Subsitute
% this with your own data matrix.
th=0.2;
A=double(rand(10,10,10)<th);
A(1,1,1)=2;
A(5,5,5)=3;
% A nice color. I just dont like the standard blue so I picked another one.
Royal_Blue=[65 105 225]/255;
%%%%%%%%%%%%%%%%%%%%%%
%% Draw cubes
% Obtain all the linear indexes (search mathworks for help between
% subscripts vs linear indices) of the locations where a cube is wanted
% (A==1)
ind=find(A==1);
% Create a figure
fig=figure();
hold on
% Draw the cubes one by one
for ii=1:length(ind)
% For each linear index get its subscript (that also
% will be x,y,z position)
[ix,iy,iz]=ind2sub(size(A),ind(ii));
% Use the drawcube function to draw a single cube in the
% desired position with the desired size (1) and colour.
drawCube([ix,iy,iz],1,Royal_Blue);
end
% Nice plotting code. This just makes the drawing nicer.
camlight left
lighting gouraud
axis equal
axis off
view(-50,25)
%%%%%%%%%%%%%%%
%% Now draw the spheres
% This code is the same as the previous one but I just draw
% spheres instead of cubes.
ind=find(A>1);
% create an sphere
[X,Y,Z] = sphere;
for ii=1:length(ind)
[ix,iy,iz]=ind2sub(size(A),ind(ii));
% scale sphere
Xs=X*A(ix,iy,iz)/2;
Ys=Y*A(ix,iy,iz)/2;
Zs=Z*A(ix,iy,iz)/2;
surf(Xs+ix,Ys+iy,Zs+iz,'edgecolor','none','facecolor',[1 1 1]);
end
% Change the background colour to black
whitebg(fig,'k')
% MAke sure it stays black
set(gcf, 'InvertHardCopy', 'off');
Function drawCube is as follows:
function drawCube( origin, size,color)
% From
% http://www.mathworks.com/matlabcentral/newsreader/view_thread/235581
if nargin<3
color='b';
end
x=([0 1 1 0 0 0;1 1 0 0 1 1;1 1 0 0 1 1;0 1 1 0 0 0]-0.5)*size+origin(1);
y=([0 0 1 1 0 0;0 1 1 0 0 0;0 1 1 0 1 1;0 0 1 1 1 1]-0.5)*size+origin(2);
z=([0 0 0 0 0 1;0 0 0 0 0 1;1 1 1 1 0 1;1 1 1 1 0 1]-0.5)*size+origin(3);
for i=1:6
h=patch(x(:,i),y(:,i),z(:,i),color);
set(h,'edgecolor','none')
end
end

Rotating a 2D array using matrix transformation

I am writing a program that needs a nxn array to be rotated about it's center. Rotations are only at 90-degree angles.
What I do is I translate the origin to the center and perform the rotation, then translate it back again.
For example,a 3x3 array:
0 0 1
0 1 1
0 1 1
when rotated 90 degrees about it's center, becomes:
1 1 1
0 1 1
0 0 0
using (1,1) as it's center, then after getting the positions relative to the center, applying the rotation transformation. The problem is when I have an even-numbered dimension, a 4x4 array for example:
0 1 1 1
1 1 1 0
0 0 0 0
0 1 0 0
What is it's center? Or rather, how do I correctly rotate the array using a transformation matrix?
Edit: assume that the arrays can contain anything, integers or maybe even objects

find largest rectangle not (necessary) aligned with image boundary in binary matrix

I am using this solution to find rectangles aligned with the image border in a binary matrix. Suppose now I want to find a rectangle that is not aligned with the image border, and I don't know its orientation; what would be the fastest way to find it?
For the sake of the example, let's look for a rectangle containing only 1's. For example:
1 1 1 1 0 0 0 0 0 1 0 0 1 1 1
0 1 1 1 1 1 0 0 0 1 0 0 1 1 0
0 0 0 1 1 1 1 1 0 1 0 0 1 0 0
0 0 0 0 0 1 1 1 1 1 0 0 0 0 0
0 0 0 0 0 0 0 1 1 1 1 1 0 0 0
0 0 0 0 0 0 0 0 0 1 1 1 1 1 0
Then the algorithm described in the solution I described above would only find a rectangle of size 6 (3x2). I would like to find a bigger rectangle that is tilted; we can clearly see a rectanble of at least size 10 or more...
I am working in C/C++ but an algorithm description in any language or pseudo-code would help me a lot.
Some more details:
there can be more than one rectangle in the image: I need the biggest only
the rectangle is not a beautiful rectangle in the image (I adapted my example above a little bit)
I work on large images (1280x1024) so I'm looking for the fastest solution (a brute-force O(n³) algorithm will be very slow)
(optional) if the solution can be parallellized, that is a plus (then I can boost it more using GPU, SIMD, ...)
I only have a partial answer for this question, and only a few thoughts on complexity or speed for what I propose.
Brute Force
The first idea that I see is to use the fact that your problem is discrete to implement a rotation around the center of the image and repeat the algorithm you already use in order to find the axis aligned solution.
This has the downside of checking a whole lot of candidate rotations. However, this check can be done in parallel since they are indepedant of one another. This is still probably very slow, although implementing it (shouldn't be too hard) and would provide a more definite answer to the question speed once parallelized.
Note that your work-space being a discrete matrix, there is only a finite number of rotation to browse through.
Other Approach
The second solution I see is:
To cut down your base matrix so as to separate the connected components [1] (corresponding to the value set you're interested in).
For each one of those smaller matrices -- note that they may be overlapping depending on the distribution -- find the minimum oriented bounding box for the value set you're interested in.
Still for each one of those, rotate your matrix so that the minimum oriented bounding box is now axis-aligned.
Launch the algorithm you already have to find the maximum axis-aligned rectangle containing only values from your value set.
The solution found by this algorithm would be the largest rectangle obtained from all the connected components.
This second solution would probably give you an approximation of the soluiton, but I believe it might prove to be worth trying.
For reference
The only solutions that I have found for the problem of the maximum/largest empty rectangle are axis-aligned. I have seen many unanswered questions corresponding to the oriented version of this problem on 2D continuous space.
EDIT:
[1] Since what we want is to separate the connected component, if there is a degree of overlap, you should do as in the following example:
0 1 0 0
0 1 0 1
0 0 0 1
should be divided into:
0 0 0 0
0 0 0 1
0 0 0 1
and
0 1 0 0
0 1 0 0
0 0 0 0
Note that I kept the original dimensions of the matrix. I did that because I'm guessing from your post it has some importance and that a rectangle expanding further away from the boundaries would not be found as a solution (i.e. that we can't just assume there are zero values beyond the border).
EDIT #2:
The choice of whether or not to keep the matrix dimensions is debatable since it will not directly influence the algorithm.
However, it is worth noting that if the matrices corresponding to connected components do not overlap on non-zero values, you may choose to store those matrices "in-place".
You also need to consider the fact that if you wish to return as output the coordinates of the rectangle, creating a matrix with different dimensions for each connected component, this will force you to store the coordinates of your newly created matrix in the original one (actually, one point, say for instance the up-left one, should be enough).

Radial basis network character recognition

I want to develop a simple character recognition program by implementing a given neural network kind; a simple command line-type is enough.
The radial basis function neural network was assigned to me and I already studied the weight training, input-to-hidden-to-output procedures but I am still doubtful of in implementing it. My references are (1) and (2).
A simple one-dimensional array of a 10 by 10 binary object (that represents a character) is the input. For example, the array below
input = array(
0,0,0,1,1,1,1,0,0,0,
0,0,1,0,0,0,0,1,0,0,
0,1,0,0,0,0,0,0,1,0,
1,0,0,0,0,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,1 )
is the representation of the character "A":
0 0 0 1 1 1 1 0 0 0
0 0 1 0 0 0 0 1 0 0
0 1 0 0 0 0 0 0 1 0
1 0 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
I plan to take the total weight of the input and compare it to the training set as in the saved 1-D arrays of the other characters of the alphabet and the one with the closest is the prediction.
The problem is I tend to understand algorithms better if presented in a CLRS-manner or similar type as opposed to mathematical formula. I find it hard to understand the explanations in those two papers (which I find the easiest to read among others here in the Google search).
Can someone point me to a friendly algorithm for a RBNFF that takes in an array and produces an output of weights? If not, a paper that explains this in Layman's manner would be appreciated.
Training
For what I could find there is no "one right way" to train them.
The simplest training I could find was by a composition of two algorithms
(Clustering) Taking the left part (input weights and RBFs) of the network and doing unsupervised clustering. There is a few things you can try out hard/soft and the number of clusters/RBFs.
Each cluster is a representation of a single RBF with the weights connecting to it.
How you go from having clusters to get rbf and rbf weights depends on what clustering you are using. (I can extend this if it's unclear)
(Neural Network) The solving the left out part of the original RBFNN from the last step by using the output from the clustering as input to an ordinary single layer neural network.
Probably easier to find these more primitive algorithms easily explained
EDIT
found some "pseudo"-code with explanations that might explain it all better (written in C#)
http://msdn.microsoft.com/en-us/magazine/dn532201.aspx
(Supposedly) working python code
https://github.com/andrewdyates/Radial-Basis-Function-Neural-Network

Resources