Read and display gray scale images in C language. - c

I want to load gray scale images in C, pre process it and then display the modified image. My question is:
What is the right way to import gray scale images(jpeg,png formats)in C language ?
My own search before asking this question.
1- fread or with file management, we can read image but data will be encrypted(compressed), I want gray scale values(0-255) of each pixel.
2- There is one API ImageMagick which can be helpful but it is having installation problem with Mac OS X.
I have done image processing in python and matlab but have no idea about C language.
Thanks

You have a number of options, but I will go through them starting with the easiest and least integrated with OSX, and getting progressively more integrated with OSX.
Easiest Option
Personally, if I was intent on processing greyscale images, I would write my software to use NetPBM's Portable Greymap (PGM) format as that is the very simplest to read and write and readily interchangeable with other formats. There is no compression, DCT, quantisation, colorspaces, EXIF data - just your data with a simple header. The documentation is here.
Basically a PGM file looks like this:
P2
# Shows the word "FEEP" (example from Netpbm man page on PGM)
24 7
15
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 3 3 3 3 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 15 15 15 0
0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 15 0
0 3 3 3 0 0 0 7 7 7 0 0 0 11 11 11 0 0 0 15 15 15 15 0
0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 0 0
0 3 0 0 0 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
You can see the P2 says it is in ASCII (easy to read) and a greymap. Then the next line says it is 24 pixels wide by 7 tall and that the brightest pixel is 15. Very simple to read and write. You can change the P2 to P5 and write everything after the MAXVAL in binary to save space.
Now you can just use ImageMagick outside your program to convert JPEG, PNG, GIF, TIFF files to PGM like this - without needing any linking or libraries or compiler switches:
convert input.png output.pgm
convert input.jpg output.pgm
Likewise, when you have finished processing and created your resulting output file in PGM format you can convert it to JPEG or TIFF by simply reversing the parameters:
convert result.pgm result.jpg
Personally, I would install ImageMagick using homebrew. You go to the homebrew website and copy the one-liner and paste it into a terminal to install homebrew. Then you can install ImageMagick with:
brew install imagemagick
and, by the way, if you want to try out the other suggestion here, using OpenCV, then that is as easy as
brew search opencv
brew install homebrew/science/opencv
If you want a small, self-contained example of a little OpenCV project, have a look at my answer to another question here - you can also see how a project like that is possible from the command line with ImageMagick in my other answer to the same question.
Magick++
If you choose to install ImageMagick using homebrew you will get Magick++ which will allow you to write your algorithms in C and C++. It is pretty easy to use and can run on any platforms, including OSX and Windows and Linux so it is attractive from that point of view. It also has many, many image-processing functions built right in. There is a good tutorial here, and documentation here.
Your code will look something like this:
// Read an image from URL
Image url_image("http://www.serverName.com/image.gif");
// Read image from local filesystem
Image local_file_image("my_image.gif");
// Modify image
Pixels my_pixel_cache(my_image);
PixelPacket* pixels;
// define the view area that will be accessed via the image pixel cache
int start_x = 10, start_y = 20, size_x = 200, size_y = 100;
// return a pointer to the pixels of the defined pixel cache
pixels = my_pixel_cache.get(start_x, start_y, size_x, size_y);
// set the color of the first pixel from the pixel cache to black (x=10, y=20 on my_image)
*pixels = Color("black");
// set to green the pixel 200 from the pixel cache:
// this pixel is located at x=0, y=1 in the pixel cache (x=10, y=21 on my_image)
*(pixels+200) = Color("green");
// now that the operations on my_pixel_cache have been finalized
// ensure that the pixel cache is transferred back to my_image
my_pixel_cache.sync();
// Save results as BMP file
image.write(“result.bmp”);
Apple OSX Option
The other ENTIRELY SEPARATE option would be to use the tools that Apple provides for manipulating images - they are fast and easy to use, but are not going to work on Linux or Windows. So, for example, if you want to
a) load a PNG file (or a TIFF or JPEG, just change the extension)
b) save it as a JPEG file
c) process the individual pixels
// Load a PNG file
NSImage * strImage = [[NSImage alloc]initWithContentsOfFile:#"/Users/mark/Desktop/input.png"];
// Save NSImage as JPG
NSData *imageData = [strImage TIFFRepresentation];
NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageData];
NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:1.0] forKey:NSImageCompressionFactor];
imageData = [imageRep representationUsingType:NSJPEGFileType properties:imageProps];
[imageData writeToFile:#"/Users/Mark/Desktop/result.jpg" atomically:YES];
// Access individual pixels
int w=imageRep.pixelsWide;
int h=imageRep.pixelsHigh;
int bps=imageRep.bitsPerSample;
printf("Dimensions: %dx%d\n",w,h);
printf("bps: %d\n",bps);
// Get a pointer to the uncompressed, unencoded pixel data
unsigned char *pixelData = [imageRep bitmapData];
for(int j=0;j<10;j++){
printf("Pixel %d: %d\n",j,pixelData[j]);
}
Of course, you could take the code above and easily make a little utility that converts any file format to PGM and then you could go with my first suggestion of using PGM format and wouldn't need to install ImageMagick - although it is actually dead simple with homebrew.
Bear in mind that you can mix Objective-C (as in the last example) with C++ and C in a single project using clang (Apple's compiler), so you can go ahead in C as you indicate in your question with any of the examples I have given above.
If you are new to developing on OSX, you need to go to the AppStore and download, for free, Apple's Xcode to get the compiler and libraries. Then you must do
xcode-select --install
to install the command-line tools if you wish to do traditional development using Makefiles and command-line compilation/linking.

This answer is an attempt to demonstrate how to develop with ImageMagick's MagickWand API with Xcode, and is based on the comments from the OP.
After installing ImageMagick, start a new Xcode command-line C project. Before writing any code, you need to tell llvm about the ImageMagick resources/libraries/etc.
There are many, many, ways to achieve this, but here's the quickest I can think of.
Navigate to top-level project's "Build Settings"
Under "All" (not "Basic") search for "Other Linker Flags"
Outside of Xcode, open up Terminal.app and enter the following
MagickWand-config --ldflags
Enter the output from Terminal.app as the value for "Other Linker Flags"
Back in the settings search; enter "Other C Flags"
Back in Terminal.app run the following
MagickWand-config --cflags
Enter the resulting output as the value for "Other C Flags"
Over in file main.c, you should notice Xcode picking-up MagickWand commands right away.
Try the following (needs X11 installed) ...
#include <stdio.h>
#include <wand/MagickWand.h>
int main(int argc, const char * argv[]) {
MagickWandGenesis();
MagickWand * wand;
wand = NewMagickWand();
MagickReadImage(wand, "wizard:");
MagickQuantizeImage(wand, 255, GRAYColorspace, 0, MagickFalse, MagickTrue);
MagickDisplayImage(wand, ":0");
wand = DestroyMagickWand(wand);
MagickWandTerminus();
return 0;
}
... and build + run to verify.
edit
To get the gray scale (0-255) value for each pixel, you can invoke a pixel iterator (see second example here), or export the values. Here is an example of dynamically populating a list of gray values by exporting...
// Get image size from wand instance
size_t width = MagickGetImageWidth(wand);
size_t height = MagickGetImageHeight(wand);
size_t total_gray_pixels = width * height;
// Allocate memory to hold values (total pixels * size of data type)
unsigned char * blob = malloc(total_gray_pixels);
MagickExportImagePixels(wand, // Image instance
0, // Start X
0, // Start Y
width, // End X
height, // End Y
"I", // Value where "I" = intensity = gray value
CharPixel, // Storage type where "unsigned char == (0 ~ 255)
blob); // Destination pointer
// Dump to stdout
for (int i = 0; i < total_gray_pixels; i++ ) {
printf("Gray value # %lux%lu = %d\n", i % width, i / height, (int)blob[i]);
}
/** Example output...
* Gray value # 0x0 = 226
* Gray value # 1x0 = 189
* Gray value # 2x0 = 153
* Gray value # 3x0 = 116
* Gray value # 4x0 = 80
* ... etc
*/

You can install ImageMagick on OS/X with this command:
sudo port install ImageMagick
You can get the macports package from https://www.macports.org

Don't have much experience with Mac's but I have quite a lot with OpenCV. Now granted a lot of OpenCV is in C++ (which may or may not be a problem) however it definitely supports everything you want to do and more. It's very easy to work with has lot's of helpful wiki's and a very good community.
Link to installing on Mac: http://blogs.wcode.org/2014/10/howto-install-build-and-use-opencv-macosx-10-10/
Link to some OpenCV wikis: http://opencv.org/documentation.html
EDIT:
I should also mention that older versions of OpenCV are in C and a lot of the functions are still supported if you chose to go the C route.

Related

Creating a series of 2-dimensional arrays from a text file in Julia

I'm trying to write a Sudoku solver, which is the fun part. The un-fun part is actually loading the puzzles into Julia from a text file. The text file consists of a series of puzzles comprising a label line followed by 9 lines of digits (0s being used to denote blank squares). The following is a simple example of the sort of text file I am using (sudokus.txt):
Easy 7
000009001
008405670
940000032
034061800
070050020
002940360
890000056
061502700
400700000
Medium 95
000300100
800016070
000009634
001070000
760000015
000020300
592400000
030860002
007002000
Hard 143
000003700
305061000
000200004
067002100
400000003
003900580
200008000
000490308
008100000
What I want to do is strip out the label lines and store the 9x9 grids in an array. File input operations are not my specialist subject, and I've tried various methods such as read(), readcsv(), readlines() and readline(). I don't know whether there is any advantage to storing the digits as characters rather than integers, but leading zeros have to be maintained (a problem I have encountered with some input methods and with abortive attempts to use parse()).
I've come up with a solution, but I suspect it's far from optimal:
function main()
open("Text Files\\sudokus.txt") do file
grids = Vector{Matrix{Int}}()
grid = Matrix{Int}(0,9)
row_no = 0
for line in eachline(file)
if !(all(i -> isnumber(i), line))
continue
else
row_no += 1
squares = split(line, "")
row = transpose([parse(Int, square) for square in squares])
grid = vcat(grid, row)
if row_no == 9
push!(grids, grid)
grid = Matrix{Int}(0,9)
row_no = 0
end
end
end
return grids
end
end
#time main()
I initially ran into #code_warntype problems from the closure, but I seem to have solved those by moving my grids, grid and row_no variables from the main() function to the open block.
Can anyone come up with a more efficient way to achieve my objective or improve my code? Is it possible, for example, to load 10 lines at a time from the text file? I am using Julia 0.6, but solutions using 0.7 or 1.0 will also be useful going forward.
I believe your file is well-structured, by that I mean each 1,11,21... contains difficulty information and the lines between them contains the sudoku rows. Therefore if we know the number of lines then we know the number of sudokus in the file. The code utilizes this information to pre-allocate an array of exactly the size needed.
If your file is too-big then you can play with eachline instead of readlines. readlines read all the lines of the file into the RAM while eachline creates an iterable to read lines one-by-one.
function readsudoku(file_name)
lines = readlines(file_name)
sudokus = Array{Int}(undef, 9, 9, div(length(lines),10)) # the last dimension is for each sudoku
for i in 1:length(lines)
if i % 10 != 1 # if i % 10 == 1 you have difficulty line
sudokus[(i - 1) % 10, : , div(i-1, 10) + 1] .= parse.(Int, collect(lines[i])) # collect is used to create an array of `Char`s
end
end
return sudokus
end
This should run on 1.0 and 0.7 but I do not know if it runs on 0.6. Probably, you should remove undef argument in Array allocation to make it run on 0.6.
Similar to Hckr's (faster) approach, my first idea is:
s = readlines("sudoku.txt")
smat = reshape(s, 10,3)
sudokus = Dict{String, Matrix{Int}}()
for k in 1:3
sudokus[smat[1,k]] = parse.(Int, permutedims(hcat(collect.(Char, smat[2:end, k])...), (2,1)))
end
which produces
julia> sudokus
Dict{String,Array{Int64,2}} with 3 entries:
"Hard 143" => [0 0 … 0 0; 3 0 … 0 0; … ; 0 0 … 0 8; 0 0 … 0 0]
"Medium 95" => [0 0 … 0 0; 8 0 … 7 0; … ; 0 3 … 0 2; 0 0 … 0 0]
"Easy 7" => [0 0 … 0 1; 0 0 … 7 0; … ; 0 6 … 0 0; 4 0 … 0 0]

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

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

Colorspace management in Postscript, Ghostscript, GSView

I am attempting to write some Postscript in order to produce artwork in files I can send to a printer to get some signs printed.
The printer has various requirements for PDFs, one of which is that they should use CMYK.
In all my prior use of Postscript I have used setrgbcolor and never really dealt with colorspace management, ICC profiles, etc.
One of the colours I am using is called RAL 1507 RAL 5017 (Traffic Blue) with RGB and CMYK values I obtained by using a search engine for the colour name. I checked by using an online RGB to CMYK convertor (with no specified colourspace profile)
I though I'd try setcmykcolor and created the following
%!PS-Adobe3.0
%
% Test use of CMYK in Postscript in preparation for creating a PDF/A-1a file
% for use by a commercial printer.
%
%%Pages: 1
%%Page: One 1
/Hevetica-Bold 20 selectfont
0 90 255 div 140 255 div setrgbcolor
100 100 250 100 rectfill
120 130 moveto 1 setgray (RGB: 0 90 140) show
100 255 div 60 255 div 0 10 255 div setcmykcolor
100 200 250 100 rectfill
120 230 moveto 1 setgray (CMYK: 100 60 0 10) show
100 255 div 36 255 div 0 45 255 div setcmykcolor
100 300 250 100 rectfill
120 330 moveto 1 setgray (CMYK: 100 36 0 45) show
0 0 1 setrgbcolor
100 400 250 100 rectfill
120 430 moveto 1 setgray (RGB: 0 0 255) show
showpage
%%EOF
(Forgive the DSC - it's intended to be just enough to placate GSView)
GSView 5.0 on MS-Windows 10 with Ghostscript 9.05 renders it like this
I had expected at least one of the CMYK colours to be rendered much closer to the bottom RGB colour.
The colour in question is designed for printing road-signs, so I'd be surprised if it is outside the relevant colour gamut used by commercial printers.
What do I need to do to be confident the printer will print my CMYK value with a result close to what I expect from GSView's rendering of the RGB value.
I don't know where you got the CMYK values from but they are not (IMO) a good representation of the RGB colour. Try 0.74 0.44 0 0.27 setcmykcolor instead.
The numbers you have used would be reasonable, if you treated them as percentages, not as values in the range 0->255. 100% Cyan, 36% magenta 0% yellow and 45% black produces quite a respectable match. I wonder if that's your mistake ?
That would be:
1 0.36 0 0.45 setcmykcolor
By the way, I think you mean RAL 5017, not 1507 which is red.
On top of that, bear in mind that you are converting an RGB colour to CMYK, then displaying that CMYK value on an RGB monitor, which involves converting it back to RGB, so some loss of precision is to be expected.
The highly simplistic calculation given in the Red Book (PostScript Language Reference Manual) is that cyan = 1 - red, magenta = 1 - green, yellow = 1 - blue. However equal values of CMYK do not generally create black, so we also apply undercolor removal.
Take the lowest value of C, M, Y, Make that value K (black). Then subtract k from each of C, M, Y. The final result is:
c = 1 - red
m = 1 - green
y = 1 - blue
k = min (c, m, y)
cyan = c - k
magenta = m - k
yellow = y - k
black = k
For your values (mapped to values from 0-1, assuming a range of 0-255);
red = 0
green = 0.353
blue = 0.549
c = 1 - 0 = 1
m = 1 - 0.353 = 0.647
y = 1 - 0.549 = 0.451
k = 0.451
cyan = 1 - 0.451 = .549
magenta = 0.647 - 0.451 = 0.196
yellow = 0.451 - 0.451 = 0
black = 0.451
so
0.549 0.196 0 0.451 setcmykcolor
That's a cheap and cheerful calculation, its intended to be done by a PostScript interpreter in a printer, so its chosen to be quick, rather than accurate. But I think you'll see that its closer than the values you were using.
For proper colour space management the RGB colours you are using would be values in a particular RGB space, for example the colour space of your monitor. You would then use the ICC profile associated with that device to turn the RGB values into values in the CIE XYZ space (a device-independent space). Then you would choose a particular destination CMYK space (eg the printer you want to use) and would use the ICC profile asociated with the destination device to go the other way, turn the XYZ values into CMYK values.
In a properly colour managed workflow, where all the devices are characterised by ICC profiles, the result is that the colour on all the devices would be as close as it possible to get to being the same.
Of course, this relies on you having everything characterised, clearly you don't.
Note that spot colours (/Separation colours in PostScript and PDF) are somewhat 'different'. These are intended to be printed using the specific ink so there's no need to characterise the values, 50% Pantone 1495 is an absolutely accurate value.
However, if your printer isn't equipped to print that colour, because for example your doing a quick check on your local CMYK printer, these colours are normally defined to have an 'alternate' representation. Ideally these would be CMYK values which will print something which is not entirely unlike the desired colour. Some ink manufacturers specify an alternate representation which is not a particularly good representation of the actual colour, arguably because they have a number of inks which map to the same colour in CMYK, so they use 'off' values to be able to tell the difference. Suspicious users have been known to comment that its done to make sure you can't do a decent print without using the manufacturers inks.....

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).

Import a binary image from matlab to a "C" program

I have a binary image in Matlab, and I need the binary array(0 and 1) in a C program,
How can I import it?
I can save the binary image in Matlab as ".mat" but I don't know how to read the mat file in C.
Also I thought maybe I can save the binary image in Matlab as ".bin" which is readable in "C" but again I don't know how to save an image in matlab as ".bin".
Any help would be greatly appreciated.
You can also write your data to a binary file, which will be about twice smaller then text.
img=rand(10)>.5; %# an array from #Amro's answer
fid = fopen('test.bin','w');
fwrite(fid,img,'int8')
fclose(fid);
Then I believe you can read it in C without problems. Remember, MATLAB will write data by columns, not by rows - first 1st column, then 2nd, etc. If you want to read it in C by rows, just transpose the array before writing:
fwrite(fid,img','int8') %# notice ' symbol after img
First of all, check the net using a searching engine. The place to search in first is of course Mathworks, where you can find docs like this. The second step, since it looks complicated to write from scratch a converter, is to search if your need is already someone else need. A link like this could be useful, but there's the requirements of a MATLAB itself (linking with one of its libraries, the MAT-file interface library I suppose). I believe it is however the simpler thing to do.
The next simple solution is to use this with a format we know we can read, If the input array is of class logical, imwrite assumes the data is a binary image and writes it to the file with a bit depth of 1, if the format allows it. BMP, PNG, or TIFF formats accept binary images as input arrays.
BMP images are not hard to be handled by custom routines; for PNG images, you can use png library, and for TIFF, I can't remember, but you can search or choose the other options.
Here other ways of saving data are explained; a plain ascii file could be also easy to be parsed by custom C routines.
>> img=rand(10)>.5
img =
1 0 1 1 0 0 1 1 0 0
1 1 0 0 0 1 0 0 1 0
0 1 1 0 1 1 1 1 1 1
1 0 1 0 1 0 1 0 1 1
1 1 1 0 0 0 1 1 1 1
0 0 1 1 0 0 1 0 0 0
0 0 1 1 0 1 1 0 1 1
1 1 0 0 1 0 0 0 1 0
1 1 1 1 1 1 0 1 0 0
1 1 0 0 1 0 0 0 1 0
>> dlmwrite('file.dat', img, 'delimiter',' ')
If you need to export array data from Matlab and import it into a C program, one easy option (assuming the array isn't gigantic) is to use a plain text file as in intermediate. From Matlab, write the array out as strings to a text file with each element separated by a comma (for example, 1,0,0,1,0,1,1,etc). Save this as a regular ASCII text file. Now, you can open the file in C with fopen, read in a character at a time with fgetc, and reconstruct the array.
For example, the C portion might look like:
FILE* fp;
char inp[3];
int array[PLENTY_OF_ROOM], index=0;
fp = fopen("exported_data.txt", "r");
while (fgets(inp, 3, fp) != NULL) {
if ((inp[0] == '0' || inp[0] == '1') && inp[1] == ',')
array[index++] = inp[0] - '0';
else {
fprintf(stderr, "Error: bad format\n");
exit(1);
}
}
On some platforms (like Windows) you have to specify "binary" when opening the file, otherwise read/written bytes can be interpreted as special characters and may not be read/written to the file as expected:
FILE* fin,fout;
...
fin = fopen("file1.bin", "rb"); // the 'b' indicates "binary"
fout = fopen("file1.bin", "wb"); // the 'b' indicates "binary"

Resources