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

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"

Related

How to get data from specific input file format skipping line with scanf [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I have a .txt file that contains info like this:
9:0
B1 0 0 0 0 0
B2 0 0 0 0 0
B3 4 5 0 0 0
B4 1 2 3 0 0
9:1
B1 0 0 0 0 0
B2 0 0 0 0 0
B3 4 5 0 0 0
B4 1 2 3 0 0
9:2
B1 0 0 0 0 0
B2 0 0 0 0 0
B3 4 5 0 0 0
B4 1 2 3 0 0
(...)
As you can see, the format is a line with the time, and the next four lines is the identifier of "B" followed by five elements of an array.
I can easily read the whole file, looping through the whole file (I know how many lines the file has) using first of all scanf to get the date, next another scanf to read the "B" plus the identifier, and loop four times with scanf again to get the integers of the array and go back to get the time.
This works fine, but (again) as you can see, there's a lot of zeros in the array space, and it would be a lot faster if I check the first element and if it is zero, then skip and read the next box, so I did it and used the break; statement, but the problem is that using break will ruin the structure of my loop, storing in the time variable a B identifier sometimes.
I'm wondering if there's any other way to skip the zeros when I find one, and jump to the next B identifier, i.e. after reading 9:0, i get B1 and then read the first zero, so skip this line and get 'B2' until I find a non-empty array.
If anyone could help me, please!
I think a reasonably fast solution might be to read the entire line into a static char array, skipping to the next line if the 4'th character is 0, and using sscanf to read the values otherwise.
My reasoning here is that the work of fscanf is split between (1) reading in a string from a file, and (2) parsing that string into numbers, and moving them into the provided variables. However, I know IO operations can be pretty slow, so here is another alternative that does slightly less IO.
Use fscanf to read in only the first two tokens of a line (namely, the B_ and the first number), and use fseek to skip to the next line if the first number is 0. I'm not super confident that this will be faster, but its something you could try.

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]

Haskell file reading and finding values

I have recently started learning Haskell and I'm having a hard time figuring out how to interpret text files.
I have following .txt file:
ncols 5
nrows 5
xllcorner 809970
yllcorner 169790
cellsize 20
NODATA_value -9999
9 0 0 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 0 0
0 2 0 0 3
The first 6 lines just display some information I need when working with the file in a GIS software. The real deal starts when I try to work with the numbers below in Haskell.
I want to tell Haskell to look up where the numbers 9, 1, 2 and 3 are and print back the number of the row and column where those numbers actually are. In this case Haskell should print:
The value 9 is in row 1 and column 1
The value 1 is in row 2 and column 2
The value 2 is in row 5 and column 2
The value 3 is in row 5 and column 5
I tried finding the solution (or at least similar methods for interpreting files) in tutorials and other Haskell scripts without any success, so any help would be greatly appreciated.
Here is an example of a script to do what you want. Note that this will in its current form does not fail gracefully (but given this is a script, I doubt this is a concern). Make sure there is a trailing newline at the end of your file!
import Control.Monad (replicateM, when)
import Data.Traversable (for)
import System.Environment (getArgs)
main = do
-- numbers we are looking for
numbers <- getArgs
-- get the key-value metadata
metadata <- replicateM 6 $ do
[key,value] <- words <$> getLine
return (key,value)
let Just rows = read <$> lookup "nrows" metadata
Just cols = read <$> lookup "ncols" metadata
-- loop over all the entries
for [1..rows] $ \row ->do
rawRow <- words <$> getLine
for (zip [1..cols] rawRow) $ \(col,cell) ->
when (cell `elem` numbers)
(putStrLn ("The value " ++ cell ++ " is in row " ++ show row ++ " and column " ++ show col))
To use it, pass it as command line arguments the numbers you are looking for and then feed as input your data file.
$ ghc script.hs
$ ./script 9 1 2 3 < data.txt
Let me know if you have any questions!
I wasn't really sure if you wanted to look up just a fixed set of numbers, or any non-zero number. As your question asked for the former, that is what I did.

substituting some elements of a matrix with new values bash

I am trying to read in a file, change some parts of it and write it to a new file in bash. I know that I can substitute the parts with the "sed" command but I do not know how to it in my case which is a matrix in the beginning of my file. Here is how my file looks like
alpha
1 0 0
0 1 0
0 0 1
some text here
more numbers here
and I am trying to substitute the values of the matrix above in a for loop like
for i in 1 2 3 4
do
replace 1 0 0
0 1 0
0 0 1
by 1*(1+${i}) ${i}/2 0
${i}/2 1 0
0 0 1
and print the whole file with the substitution to newfile.${i}
done
I want to do this in bash. Any idea how to do this? And I only want to change this part and only this part!
Awk is more suitable for this:
for i in {1..4}; do awk -v i="$i" -f substitute.awk oldfile.txt > newfile.$i; done
using the following substitute.awk script:
{
if( NR == 3 ) { print 1 + i, i / 2, 0 }
else if( NR == 4 ) { print i / 2, 1, 0 }
else print $0
}
(assuming, as you wrote, that the matrix is always in lines 3 through 5; in your example it is in lines 2 through 4)

Read and display gray scale images in C language.

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.

Resources