Im trying to get the OCR sample app to recognise some small text and how I'm doing it is to resize the image. Once I have resized the image it is all 'pixel-ee'
I want to use the SmothGaussian method to clean it up but I get an error each time I execute the method
Here is the code:
Image<Bgr, Byte> image = new Image<Bgr, byte>(openImageFileDialog.FileName);
using (Image<Gray, byte> gray = image.Convert<Gray, Byte>().Resize(800, 600, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR, true))
{
gray.Convert<Gray, Byte>()._SmoothGaussian(4);
_ocr.Recognize(gray);
Tesseract.Charactor[] charactors = _ocr.GetCharactors();
foreach (Tesseract.Charactor c in charactors)
{
image.Draw(c.Region, drawColor, 1);
}
imageBox1.Image = image;
//String text = String.Concat( Array.ConvertAll(charactors, delegate(Tesseract.Charactor t) { return t.Text; }) );
String text = _ocr.GetText();
ocrTextBox.Text = text;
}
Here is the image:
_SmoothGaussian can only handle odd numbers as kernel size so try with 3 or 5 as argument instead.
Related
I have the following code:
SimpleDecoder decoder = new SimpleDecoder();
byte[] fileBytes = File.ReadAllBytes(filename);
Bitmap image = decoder.DecodeFromBytes(fileBytes, fileBytes.Length);
PictureBox pb = new PictureBox
{
Size = new Size(100, 100),
Image = image,
SizeMode = PictureBoxSizeMode.Zoom,
Tag = filename
};
FlpThumbnails.Controls.Add(pb);
pb.Refresh();
Application.DoEvents();
at the Bitmap image = decoder.DecodeFromBytes(fileBytes, fileBytes.Length); I get the exception thrown System.Exception: 'Invalid WebP header detected'. However, in my Windows Explorer I can see the image perfectly well.
I am using Imazen.WebP.SimpleDecoder to decode the image.
Does anyone have any ideas on how to fix this error?
Thanks.
Ok I created a solution.
In his code I did the following:
public static Bitmap DecodeFromPointer(IntPtr data, long length)
{
int w = 0, h = 0;
//Validate header and determine size
if (NativeMethods.WebPGetInfo(data, (UIntPtr)length, ref w, ref h) == 0)
{
w = 100;
h = 100;
NativeMethods.WebPGetInfo(data, (UIntPtr)length, ref w, ref h);
// throw new Exception("Invalid WebP header detected");
}
I commented out the throw new exception, and added the default thumbnail size I am using of 100,100. It still does not show the image but it continues until...
It gets a little further down the file and finds this:
// if (bd.Scan0 != result) throw new Exception("Failed to decode WebP image with error " + (long)result);
As you can see I simply commented that line out as well.
And that was all I had to do to get Imazen.WebP.SimpleDecoder to not crash on images that I can see in Explorer but not see in my .Net Application. It is true I can still not see the images but the application does not crash anymore.
I need a function how is capable to build an image based on multiple merges. So I do this
public static void mergeImagesByName(List<String> names) {
File folder;
File[] listOfFiles;
List<String> allFilesName;
folder = new File("images/");
listOfFiles = folder.listFiles();
allFilesName = new ArrayList<>();
for (File fileName : listOfFiles) {
allFilesName.add(fileName.getName());
}
List<String> imgName = names.stream().map(name -> name += ".PNG").collect(Collectors.toList());
List<String> allExistingName = new ArrayList<>();
allFilesName.stream().forEach((file) -> imgName.stream().filter((name) -> (file.equals(name))).forEach((name) -> allExistingName.add(name)));
try {
File baseImage = new File(folder, "MERGE.PNG");
BufferedImage textImage = ImageIO.read(new File(folder, "Text.PNG"));
BufferedImage image = ImageIO.read(baseImage);
int w = 800;
int h = 450;
BufferedImage combined = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics g = combined.getGraphics();
g.drawImage(image, 0, 0, null);
for (String name : allExistingName) {
BufferedImage overlay = ImageIO.read(new File(folder, name));
g.drawImage(overlay, 0, 0, null);
ImageIO.write(combined, "PNG", new File(folder, "MERGE.PNG"));
}
g.drawImage(textImage, 0, 0, null);
} catch (IOException ex) {
Logger.getLogger(MergeImages.class
.getName()).log(Level.SEVERE, null, ex);
}
}
But it's to slower for what I need... I need almost 5-8sec to execute all my images and create the result. So I'm thinking... if I will make it to run on multiple core simultaneous that will increase my speed. For example.. I've 4 core, if I will can to divide my original list of elements in 4 list and with of them will have just a quarter part or original list, these can run each of them on one core, and after all will finished I can to merge just 4 images on one. But I have no idea how to do that... So please guys, if anyone of you know how to do that please show me :D
Thx and sorry for me bad English.
The solve was really simple, I need just to use parallelStream and all work much fasted
allExistingName.parallelStream().forEach(name -> {
BufferedImage overlay = images.get(name);
g.drawImage(overlay, 0, 0, null);
});
ImageIO.write(combined, "PNG", new File(folder, "MERGE.PNG"));
That was all what I need
I'm trying to write code to convert a GIF annimation file into a base64 string and then convert it from base 64 string back into an image. The code I've written is for standard image files (i.e. Bitmap, JPEG, GIF). Animated GIFs, however, are different and obviously require a different step-by-step.
Here is the code I've written for converting an image to base64 string:
if (pbTitlePageImage.Image != null)
{
// This is the step-by-step for writing an image to binary.
string Image2BConverted;
using (Bitmap bm = new Bitmap(pbTitlePageImage.Image))
{
using (MemoryStream ms = new MemoryStream())
{
BinaryWriter bw = new BinaryWriter(ms);
bm.Save(ms, ImageFormat.Jpeg);
Image2BConverted = Convert.ToBase64String(ms.ToArray());
GameInfo.TitlePageImage = Image2BConverted;
bw.Close();
ms.Close();
GameInfo.TitlePageImagePresent = true;
ProjectNeedsSaving = true;
}
}
}
And here is the code I've written for converting a base64 string back to an image:
{
byte[] TitlePageImageBuffer = Convert.FromBase64String(GameInfo.TitlePageImage);
MemoryStream memTitlePageImageStream = new MemoryStream(TitlePageImageBuffer, 0, TitlePageImageBuffer.Length);
memTitlePageImageStream.Write(TitlePageImageBuffer, 0, TitlePageImageBuffer.Length);
memTitlePageImageStream.Position = 0;
pbTitlePageImage.Image = Bitmap.FromStream(memTitlePageImageStream, true);
memTitlePageImageStream.Close();
memTitlePageImageStream = null;
TitlePageImageBuffer = null;
}
After converting the base64 string back into an image, it must be loaded into a picturebox. The above code examples will work, but only the first image in the animation chain makes it through and thus is the only part if the animation that appears in the picturebox. I need to write code that will handle the entire animation. Thanks in advance!
I found a way to solve it:
byte[] imageByte = Base64.decodeBase64(imageData.getImageBase64());
new FileOutputStream("image2.gif");
write(imageByte);
close();
I dont know why, but using a FileOutput String i could get a file with the complete animation.
Using the Haxe programming language, is there any cross-platform way to read a PNG image, and get the pixel data from the image?
I have a file called stuff.png, and I want to obtain an array of RGB values from the image (as an integer array).
Here's an example usage of the Haxe format library to read a PNG file. You need -lib format in your compiler args / build.hxml:
function readPixels(file:String):{data:Bytes, width:Int, height:Int} {
var handle = sys.io.File.read(file, true);
var d = new format.png.Reader(handle).read();
var hdr = format.png.Tools.getHeader(d);
var ret = {
data:format.png.Tools.extract32(d),
width:hdr.width,
height:hdr.height
};
handle.close();
return ret;
}
Here's an example of how to get ARGB pixel data from the above:
public static function main() {
if (Sys.args().length == 0) {
trace('usage: PNGReader <filename>');
Sys.exit(1);
}
var filename = Sys.args()[0];
var pixels = readPixels(filename);
for (y in 0...pixels.height) {
for (x in 0...pixels.width) {
var p = pixels.data.getInt32(4*(x+y*pixels.width));
// ARGB, each 0-255
var a:Int = p>>>24;
var r:Int = (p>>>16)&0xff;
var g:Int = (p>>>8)&0xff;
var b:Int = (p)&0xff;
// Or, AARRGGBB in hex:
var hex:String = StringTools.hex(p,8);
trace('${ x },${ y }: ${ a },${ r },${ g },${ b } - ${ StringTools.hex(p,8) }');
}
}
You can always access the pixel data with BitmapData.getPixels/BitmapData.setPixels.
If you are using haXe NME, you can use Assets.getBitmapData() to load an asset image file.
If you want to load images from network, then you can use Loader class, it can asynchronous loading remote images, but in flash please mind the cross-domain issue.
For more generic ByteArray -> BitmapData conversion, use following code:
var ldr = new Loader();
ldr.loadBytes(cast(byteArray)); // bytearray contains raw image data
var dp: DisplayObject = ldr.content; // actually ontent should be of Bitmap class
var bitmapData = new BitmapData(Std.int(dp.width), Std.int(dp.height), true, 0);
bitmapData.draw(dp);
Im trying to do an experiment on how to use the HoughTransformation class of AForge. Im using this class to try to count the number of circles on an image. But I always got this error message: Unsupported pixel format of the source image.
Here is my code:
private void CountCircles(Bitmap sourceImage)
{
HoughCircleTransformation circleTransform = new HoughCircleTransformation(15);
circleTransform.ProcessImage(sourceImage);
Bitmap houghCircleImage = circleTransform.ToBitmap();
int numCircles = circleTransform.CirclesCount;
MessageBox.Show("Number of circles found : "+numCircles.ToString());
}
HoughCircleTransformation expects a binary bitmap.
private void CountCircles(Bitmap sourceImage)
{
var filter = new FiltersSequence(new IFilter[]
{
Grayscale.CommonAlgorithms.BT709,
new Threshold(0x40)
});
var binaryImage = filter.Apply(bitmap);
HoughCircleTransformation circleTransform = new HoughCircleTransformation(15);
circleTransform.ProcessImage(binaryImage);
Bitmap houghCircleImage = circleTransform.ToBitmap();
int numCircles = circleTransform.CirclesCount;
MessageBox.Show("Number of circles found : "+numCircles.ToString());
}