I want to be able to compare an image taken from a webcam to an image stored on my computer.
The library doesn't need to be one hundred percent accurate as it won't be used in anything mission critical (e.g. police investigation), I just want something OK I can work with.
I have tried a demonstration project for Image Recognition from CodeProject, and it only works with small images / doesn't work at all when I compare an exact same image 120x90 pixels (this is not classified as OK :P ).
Has there been any success with image recognition before?
If so, would you be able to provide a link to a library I could use in either C# or VB.NET?
You could try this: http://code.google.com/p/aforge/
It includes a comparison analysis that will give you a score. There are many other great imaging features of all types included as well.
// The class also can be used to get similarity level between two image of the same size, which can be useful to get information about how different/similar are images:
// Create template matching algorithm's instance
// Use zero similarity to make sure algorithm will provide anything
ExhaustiveTemplateMatching tm = new ExhaustiveTemplateMatching(0);
// Compare two images
TemplateMatch[] matchings = tm.ProcessImage( image1, image2 );
// Check similarity level
if (matchings[0].Similarity > 0.95)
{
// Do something with quite similar images
}
You can exactly use EmguCV for .NET.
I did it simply. Just download the EyeOpen library here.
Then use it in your C# class and write this:
use eyeopen.imaging.processing
Write
ComparableImage cc;
ComparableImage pc;
int sim;
void compare(object sender, EventArgs e){
pc = new ComparableImage(new FileInfo(files));
cc = new ComparableImage(new FileInfo(file));
pc.CalculateSimilarity(cc);
sim = pc.CalculateSimilarity(cc);
int sim2 = sim*100
Messagebox.show(sim2 + "% similar");
}
Related
Im making a Random Generator with Windows Forms with Images and I use the random pick with resources pictureBox1.Image = Properties.Resources.heart;
Now, the "heart" should get removed from the List, to prevent getting "heart" again.
Here I thought, that I just use int firstCard = randomCard.Next(cards.Count); and I want to use the int firstCard as Properties.Resources.cards[firstCard], because behind Properties.Resources. comes the resource name. But the string doesnt work there, and I dont know how to fix that. Pls help.
Thank you
Pults
Add all your images to a List<Image> - if you have 100 images your list will end up with 100 things
Pick one at random and also remove it. Make the upper bound of random the number of things in the list
//do this once outside the loop that adds images: var r = new Random();
Then the loop that adds images
var x = r.Next(imageList.Count);
var i = inageList[x]; //get the image
imageList.RemoveAt(x); //can't get it again
Note that setting the image of a picture box cannot be done in addition; you'll need multiple picture boxes
Side note, you might find it easier to keep your images in an ImageList (easier to index numerically) - the documentation for it also has some useful/helpful example codes that iteratively draws images into a PictureBox
Also, someone else (maybe doing the same exercise as you :) ) wondered how to get images by string name..
Oh yeah, someone asked the same, didnt find it.
Yea the "ResourceManager.GetObject" is exactly what I needed.
Thanks for the quick response and instant solve!
I would like to ask for some insight/assistance on how I might improve my OCR accuracy. My target images are low resolution (screenshots) and I would very much prefer not to upscale them, as my program needs to perform fast.
I have 2 images. I see no apparent difference between them, however tesseract is having trouble with one.
image 1 image2
The first image is the issue, the result I am getting is: 251\n41\n31\n\n11\n11\n\n11\n
As you can see, there is something wrong with how it's handling the spacing. There are 2x new lines when things start to go wrong.
Meanwhile, in the second image I get the expected result: 300\n60\n40\n\n1\n15\n15\n10\n6\n15\n
These images were created through the following preprocessing steps:
image.Alpha(AlphaOption.Remove);
image.BlackThreshold(new Percentage(27));
image.Negate(); // Original image has white text on black background
I have limited tesseract's charset to only digits (01234567890-).
I have tried various segmentation modes (SparseText, SingleColumn, SingleBlock). I am running Tesseract 4.1. Do you guys have any pointers?
Or maybe you could tell me what resize algorithm is fast and good for OCR?
If you are having issues with Tesseract and are considering using a more robust library without the need for training, you can try using a commercial library such as Leadtools. With the Leadtools OCR toolkit, I was able to get perfect results for both images with only the basic image processing built in to the OCR demo. There are, however, more sophisticated image processing functions that you can use for more complex tasks if need be. Besides the OCR demo, I was also able to get the same results, in JSON form, without any preprocessing, from one of the tutorials posted here below. As a disclaimer, I work for this vendor.
https://www.leadtools.com/help/sdk/v21/tutorials/dotnet-console-export-ocr-results-to-json.html
Here's some simplified source code that would achieve the same task for one image and print out the raw text:
// Create a new OCR engine with the default settings
IOcrEngine ocrEngine = OcrEngineManager.CreateEngine(OcrEngineType.LEAD);
ocrEngine.Startup(null, null, null, null);
// Create an OCR document to hold everything
using (IOcrDocument ocrDocument = ocrEngine.DocumentManager.CreateDocument()){
// Add the input image as a new page
using(IOcrPage page = ocrDocument.Pages.AddPage(inputFilename, null)){
// Perform OCR on just the one page
page.Recognize(null);
// build a string from the recognized characters
string text = page.GetText(0);
// Show output
Console.WriteLine($"text: '{text}'");
}
}
The results I got for the two images were "251\r\n41\r\n31\r\n1\r\n11\r\n11\r\n7\r\n4\r\n11\r\n" and "300\r\n60\r\n40\r\n1\r\n15\r\n15\r\n10\r\n6\r\n15\r\n".
I am currently building an application which is able to access a number of USB webcams. I am well aware that there is no method which can count the number of camera devices on a machine, however, whenever I try to access a camera with a wrong index, I get a black image. Is there some way to use this image to denote a limit?
For example, I have two webcams. The application retrieves frames from the first camera at index 0, and from the second camera at index 1. When i increment index to 2, all I get is a black screen (obviously, since there is no 3rd camera attached).
So far the only way how to go about this is to access every single pixel in a 320x240 bitmap and check that it is black. This is not very efficient so maybe there's some other way of doing this which I am overlooking.
Thanks for your time.
An easy way would be going with openFrameworks, which has a class called ofVideoGrabber. With its listDevices() method you can list all available cams and choose the one you want to use.
Next thing you need: ofxCv is an alternative OpenCV wrapper for openFrameworks, which you can use to transfer the images grabbed by ofVideoGrabber to OpenCV or for the rest of the processing.
So you could do something like this:
// Inside Foo.h
#include "ofxCv.h"
// import namespaces for OpenCV & ofxCv
using namespace cv;
using namespace ofxCv;
// vars we need
ofVideoGrabber vidGrabber;
ofImage inputImg;
Mat matImg;
// setup video grabber
vidGrabber.setVerbose(true);
vidGrabber.setDeviceID(1); // choose the right one via vidGrabber.listDevices()
vidGrabber.initGrabber(320,240,false);
int grabW = vidGrabber.width;
int grabH = vidGrabber.height
// grab current frame
vidGrabber.grabFrame();
inputImg.setFromPixels(vidGrabber.getPixels(), 320, 240, OF_IMAGE_COLOR);
// get cv::Mat
matImg = toCv(inputImg).clone();
... further processing ...
Hope it helps!
Yes, there is method can count cameras.
you have to use directshow or directshow.net.
IEnumMoniker.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms692852%28v=vs.85%29.aspx
I have a source image like left picture and a set of elements like right picture: Source Image And Elements...
..and I need to generate a mosaic picture like this.
But until this moment I have not worked with images, аnd I do not know where I should start.
I worked several years with C#, but you can give examples in other similar languages.
The result image you gave is apparently a ministeck pattern - in 2011 they had a downloadable software that seemed to do what you want. (Which is not available anymore by ministeck directly, but it seems that pfci.de still provides a download).
So, if you're just looking to generate the patterns for ministeck out of a given image, use their software. If you're after an algorithm to achieve something different, this won't help.
EDIT
Ok, if you're after analyzing your image, you need to load it into an object like this:
using(Bitmap b = new Bitmap(yourFileName))
{
MessageBox.Show(string.Format("image size {0} by {1} pixels", b.Width, b.Height));
MessageBox.Show(string.Format("color of pixel (100,100) is {0}", b.GetPixel(100, 100).ToString()));
}
The Bitmap object has several properties and methods that will help you to analyze the image content. Try this to get started with analyzing your image, and don't forget to either dispose your bitmap afterwards or wrap it into a using statement as shown above ...
The application I am working on currently requires functionality for Perspective Image Distortion. Basically what I want to do is to allow users to load an image into the application and adjust its perspective view properties based on 4 corner points that they can specify.
I had a look at ImageMagic. It has some distort functions with perpective adjustment but is very slow and some certain inputs are giving incorrect outputs.
Any of you guys used any other library or algorithm. I am coding in C#.
Any pointers would be much appreciated.
Thanks
This seems to be exactly what you (and I) were looking for:
http://www.codeproject.com/KB/graphics/YLScsFreeTransform.aspx
It will take an image and distort it using 4 X/Y coordinates you provide.
Fast, free, simple code. Tested and it works beautifully. Simply download the code from the link, then use FreeTransform.cs like this:
using (System.Drawing.Bitmap sourceImg = new System.Drawing.Bitmap(#"c:\image.jpg"))
{
YLScsDrawing.Imaging.Filters.FreeTransform filter = new YLScsDrawing.Imaging.Filters.FreeTransform();
filter.Bitmap = sourceImg;
// assign FourCorners (the four X/Y coords) of the new perspective shape
filter.FourCorners = new System.Drawing.PointF[] { new System.Drawing.PointF(0, 0), new System.Drawing.PointF(300, 50), new System.Drawing.PointF(300, 411), new System.Drawing.PointF(0, 461)};
filter.IsBilinearInterpolation = true; // optional for higher quality
using (System.Drawing.Bitmap perspectiveImg = filter.Bitmap)
{
// perspectiveImg contains your completed image. save the image or do whatever.
}
}
Paint .NET can do this and there are also custom implementations of the effect. You could ask for the source code or use Reflector to read it and get an idea of how to code it.
If it is a perspective transform, you should be able to specify a 4x4 transformation matrix that matches the four corners.
Calculate that matrix, then apply each pixel on the resulting image on the matrix, resulting in the "mapped" pixel. Notice that this "mapped" pixel is very likely going to lie between two or even four pixels. In this case, use your favorite interpolation algorithm (e.g. bilinear, bicubic) to get the interpolated color.
This really is the only way for it to be done and cannot be done faster. If this feature is crucial and you absolutely need it to be fast, then you'll need to offload the task to a GPU. For example, you can call upon the DirectX library to apply a perspective transformation on a texture. That can make it extremely fast, even when there is no GPU because the DirectX library uses SIMD instructions to accelerate matrix calculations and color interpolations.
Had the same problem. Here is the demo code with sources ported from gimp.
YLScsFreeTransform doesn't work as expected. Way better solution is ImageMagic
Here is how you use it in c#:
using(MagickImage image = new MagickImage("test.jpg"))
{
image.Distort(DistortMethod.Perspective, new double[] { x0,y0, newX0,newY0, x1,y1,newX1,newY1, x2,y2,newX2,newY2, x3,y3,newX3,newY3 });
control.Image = image.ToBitmap();
}