Without using System.Drawing?
I have a C# application that receives a list of filepaths pointing to a number of .PNG files. I would like to extract an array of pixel (color) data from the image, but I am having trouble determining the best way to extract that.
I had originally hoped to be able to use System.Drawing, as outlined in this answer, but I am unable to access System.Drawing, since my application (Unity3d) uses OpenGL (and therefore, is incompatible with System.Drawing)
The PngBitmapDecoder is likewise out of reach of the application. Is there any other way I can extract the data I'm interested in, short of writing my own PNG Decoder?
If you are using Unity, then you have access to their API which does exactly what you need.
http://docs.unity3d.com/Documentation/ScriptReference/Texture2D.LoadImage.html
http://docs.unity3d.com/Documentation/ScriptReference/Texture2D.GetPixels.html
http://docs.unity3d.com/Documentation/ScriptReference/Texture2D.GetPixels32.html
Related
I'm using EmguCV (It is .Net wrapper to the OpenCV image processing library).
I need to compare two images and check if this is the same person in both images.
Yes. But not directly in emgu, unless you want to make a lot of code.
Have a look at this page https://azure.microsoft.com/en-us/services/cognitive-services/face/
Here you supply two images and get score back.
It should be easy implementing the API
I've developed a Silverlight application that needs to compress JPEG images on the client. I've been using a library called FJCore to achieve this goal.
One of the biggest issues I'm encountering, however, is the fact that this toolkit requires you to convert the JPEG to a WriteableBitmap first which strips off all the metadata associated with the JPEG such as EXIF, XMP, JFIF, etc. I've modified the source of the FJCore library to persist the EXIF, compress the image, and then reattach the EXIF data. This process works but loses other types of metadata information.
Instead of having to implement a function that saves and writes each different type of metadata that exists for the JPEG format, I am looking for a simplified approach that will allow me to extract all metadata, regardless of type or format, use the FJCore toolkit to compress/resize that image, and then reattach all the previously saved metadata. Some direction or sample code that could help me achieve my goal would be greatly appreciated. Remember, this is a Silverlight application, so those .NET libraries are what I have to work with.
Thank you.
You can do this using FJCore aka ImageTools. All you need to do is add this on line 212:
// Exif. Do something?
headers.Add(header);
https://github.com/briandonahue/FluxJpeg.Core/blob/master/FJCore/Decoder/JpegDecoder.cs
And make sure you copy those headers when resizing:
jpegOut = new DecodedJpeg(
new ImageResizer(jpegIn.Image)
.Resize(320, ResamplingFilters.NearestNeighbor),
jpegIn.MetaHeaders); // Retain EXIF details
Recompile and you should be good to go.
Hi and thanks for looking!
Update
For the sake of clarity, a third-party .NET library is just fine. Preferably an open-source or free one. The solution need not be native .NET.
Background
I am working on an enterprise web application for which the client has given us thousands of pages of content in MS Word documents that we have to parse, extract data, and send to the content database.
Within these docs are various embedded images representing a larger original image in a separate folder.
The client did not provide any paths to the original source image, so when we see content with an embedded image in the MS Word doc, we have to go through several "assets" folders and look for the corresponding image which is extraordinarily time consuming.
We are already using DocX to parse the documents, so you can assume that we have a list of bitmap images to loop through that we have pulled from the document.
Question
Given a list of bitmaps that we just extracted from the document, how do we search a different folder containing hundreds of images, for the matching image, and then return the file path to it?
TinEye.com does this over the web. I am wondering if, using System.Drawing or something, we can do it on a PC with C#.
Thanks!
Matt
Hate to propose an answer to my own question, but I think I might be on to something here. Here is heuristic/pseudo code for a C# forms app--your thoughts are appreciated:
Part 1
Using System.IO, traverse the "assets" folders and get all images.
For each image, Base64 encode it.
Take the resulting string and place in an XML file:
<Image>
<Path>C:\SomePath</Path>
<EncodedString>[Some Base64 String]<Encoded String>
</Image>
Now we have an XML file containing all original images, in Base64 form, along with their file path.
Part 2
Using DocX, extract all images from MS Word Doc.
For each image, use Linq-to-Xml to search for an exact match in the XML file from Part 1.
If there are no exact matches, start iterating the XML file and computing the Levenshtein distance.
While in the foreach store the XML node Id (or file path) and Levenshtein Distance as a key value pair in an object.
Take the k/v pair with the lowest LD score and return the file path.
For performance, set tolerance so that the foreach stops if a certain original image has an acceptably low LD score when compared to the image extracted from the document.
Since this is a one-off task, I don't need instant performance. So, I could run this tonight before leaving the office and, hopefully, come back tomorrow to a list of paths connecting the original images to the ones embedded in the docs.
UPDATE
The heuristic above worked beautifully! I ended up using the Sift library to efficiently calculate distances between Base64 strings. Specifically, I used their FastDistance() method. Having 100% accuracy on finding the images I need, even if the angle from which the photo was taken is slightly different.
There is no built-in algorithm in the .NET framework for generating image similarity. You'd need to use a third-party library or do it yourself. Lots of image similarity algo questions on SO:
Algorithm for finding similar images
How can I measure the similarity between two images?
comparing images programmatically - lib or class
One more, for .NET: Are there any OK image recognition libraries for .NET?. This one refers you to AForge, which seems to have the algorithm that you are after.
According to this SO answer to a similar question, you should look at OpenCV and VLFeat. The former has a C++ API and the latter a C API, so you would need to write your own P/Invoke wrapper or perhaps wrap them in a C++/CLI facade, which you could call from C#.
Is this possible or do I have to use WPF. I am new to Winforms and have created a couple simple applications, now I need to read a TIFF file and then display a subsection of it...
I tried doing something like this:
Graphics g = e.Graphics;
Bitmap b = new Bitmap(Image.FromFile(#"W:\ILHSR_Merged_2011\compressed\overviews\ILHSR11_0405-101-1.tif"));
g.DrawImage(b, 10, 10, 350, 300);
But I get out of memory exceptions. Can someone point me to some readin, or is this simply something that should be developed in WPF.
I think you need to implement you own TIFF loader using libTiff.
TIFF image format allow to store image data in tiles. LibTiff allows you to load single tiles: in this way you can display only portion of the image (without decoding the entire TIFF!, that can have prohibitive sizes).
Unfortunately, I don't think that .NET imaging supports that TIFF feature. My suggestion is to wrap libTiff in a library written in C++/CLI, and integrate it in your application.
(Due comment: if some existing library has already wrapped libTiff, and its interface match nicely with your application, even the better)
If you need to display parts, consider using tiled Tif files, and possibly even image pyramids (see TIF pyramid for background info on how to create/use them) tif files. All of these can be read with LibTiff and LibTiff.NET
Of course this depends on how often you need to do it. My experience is that very large bitmaps cannot be displayed properly using 32bit windows versions, unless the file itself is tiled. I have made a wrapper for LibTiff.NET, which allows Tile access also for non tiled (uncompressed, or line based) files. Of course, access is slower then; you'd need to read the entire rows which are on display. Still response time was reasonable for gigapixel images.
BitMiracle LibTiff.NET mentioned in previous post/comment works great: see How to implement pan/zoom on gigapixel bitmaps? and How to implement pan/zoom on gigapixel bitmaps?; it is a native c# implementation of LibTiff, which I found easier to handle than a wrapper class (because there is no unmanaged memory blocks to take care of in c# app).
[Edit]Added link to TIF pyramid image documentation[/Edit]
I have a raw pixel data in a byte[] from a DICOM image.
Now I would like to convert this byte[] to an Image object.
I tried:
Image img = Image.FromStream(new MemoryStream(byteArray));
but this is not working for me. What else should I be using ?
One thing to be aware of is that a dicom "image" is not necessarily just image data. The dicom file format contains much more than raw image data. This may be where you're getting hung up. Consider checking out the dicom file standard which you should be able to find linked on the wikipedia article for dicom. This should help you figure out how to parse out the information you're actually interested in.
You have to do the following
Identify the PIXEL DATA tag from the file. You may use FileStream to read byte by byte.
Read the pixel data
Convert it to RGB
Create a BitMap object from the RGB
Use Graphics class to draw the BitMap on a panel.
The pixel data usually (if not always) ends up at the end of the DICOM data. If you can figure out width, height, stride and color depth, it should be doable to skip to the (7FE0,0010) data element value and just grab the succeeding bytes. This is the trick that most normal image viewers use when they show DICOM images.
There is a C# library called EvilDicom (http://rexcardan.com/evildicom/) that can be used to pull the image out of a DICOM file. It has a tutorial on how to do it on the website.
You should use GDCM.
Grassroots DiCoM is a C++ library for DICOM medical files. It is automatically wrapped to python/C#/Java (using swig). It supports RAW, JPEG 8/12/16bits (lossy/lossless), JPEG 2000, JPEG-LS, RLE and deflated (zlib).
It is portable and is known to run on most system (Win32, linux, MacOSX).
http://gdcm.sourceforge.net/wiki/index.php/GDCM_Release_2.4
See for example:
http://gdcm.sourceforge.net/html/DecompressImage_8cs-example.html
Are you working with a pure standard DICOM File? I've been maintainning a DICOM parser for over a two years and I came across some realy strange DICOM files that didn't completely fulfill the standard (companies implementing their "own" twisted standard DICOM files) . flush you byte array into a file and test whether your image viewer(irfanview, picassa or whatever) can show it. If your code is working with a normal JPEG stream then from my experience , 99.9999% chance that this simply because the file voilate the standard in some strange way ( and believe me , medical companies does that a lot)
Also note that DICOM standard support several variants of the JPEG standard . could be that the Bitmap class doesn't support the data you get from the DICOM file. Can you please write down the transfer syntax?
You are welcome to send me the file (if it's not big) yossi1981#gmail.com , I can check it out , There was a time I've been hex-editing DICOM file for a half a year.
DICOM is a ridiculous specification and I sincerely hope it gets overhauled in the near future. That said Offis has a software suite "DCMTK" which is fairly good at converting dicoms with the various popular encodings. Just trying to skip ahead in the file x-bytes will probably be fine for a single file but if you have a volume or several volumes a more robust strategy is in order. I used DCMTK's conversion code and just grabbed the image bits before they went into a pnm. The file you'll be looking for in DCMTK is dcm2pnm or possibly dcmj2pnm depending on the encoding scheme.
I had a problem with the scale window that I fixed with one of the runtime flags. DCMTK is open source and comes with fairly simple build instructions.