Inaccurate results while retrieving results from image taken from iphone 4 camera - ios4

I am using ABBYY mobile SDK to retrieve text from image. if i use the image taken by my iphone 4 camera and then i place this image in resource folder of my project, it gives me correct result(refer: How to get coordinates using abbyy mobile sdk for iphone) but taking image from camera and directly processing it with SDK APIs do not give me accurate results. For eg. the result is somthing like:
"-55",
"!l",
II,
lie,
n3,
"S S--1",
"I -S s",
"^ o :=",
"'ABBYY>",
"^ Q) U",
"^ -5 -S",
"i ii",
"CL
for image (attached).
Which is not correct. I do understand the same image if i use in resource folder of my project will give me correct result . But do not give me correct result if i take this image directly from camera and process it using ABBYY SDK apis.
Please guide.

Most probably you're trying to recognize jpeg image with EXIF information about the image rotation. It is left for user to apply this rotation to the image.
The easiest solution is to use MIPO_DetectPageOrientation flag for MobileOCR recognition manager:
[fineManager setProcessingOptions:MIPO_DetectPageOrientation];
So the MobileOCR engine will try to detect page orientation.
But be aware that recognition with MIPO_DetectPageOrientation flag is over 2 times slower than without it.

Related

How to display an image with SVG in FICO Xpress Workbench

I'm working to generate an SVG image to represent a graph. For each node, I would like to display an image. As written in the documentation, to use an image, I need to use svgaddfile and svgaddimage.
I wrote this code (I copy only the interesting lines)
svgsetgraphviewbox(0, 0,max(i in V_zero_n_plus_one)X(i)+10, max(i in V_zero_n_plus_one)Y(i)+10)
svgsetgraphscale(5)
svgsetgraphpointsize(5)
svgaddgroup("Customers", "Customers", SVG_BLACK)
svgaddgroup("Depot", "Depot", SVG_BROWN)
svgaddpoint(X(0), Y(0))
svgaddtext(X(0)+0.5, Y(0)-0.5, "Depot")
svgaddfile("./city2.jpg", "city.png")
svgaddimage("city.png", X(0)+0.5, Y(0)-0.5, 20, 20)
svgaddgroup("Routes", "Delivery routes")
svgsave("vrp.svg")
svgrefresh
svgwaitclose("Close browser window to terminate model execution.", 1)
I obtain the following image:
The image is 512x512. What am I doing wrong? Tnx
There seems to be a timing issue for the uploading of the graphic file when you are using the option '1' in 'svgwaitclose' when running from Workbench (this option means that the underlying HTTP server that is run by mmsvg is stopped immediately once the SVG file has been uploaded).
You could either work with this form:
svgwaitclose("Close browser window to terminate model execution.") ! NB: the second argument defaults to value 0
or add a small delay before this statement:
sleep(2000) ! Wait for 2 seconds
svgwaitclose("Close browser window to terminate model execution.", 1)

How to make tesseract work for different kinds of images?

I am working on a digit recognition task using Tesseract and OpenCV. I did use it and came to a solution that is specific for a particular image. If I change my image I do not obtain correct results. I should change the threshold value according to the image. The steps I did was:
Cropping the image to find an appropriate region
Change image into grayscale
Using Gaussian Blur
Taking appropriate threshold
passing the image through Tesseract
So, My question is how can I make my code generic i.e. it can be used for different images without updating my code.
While working on this image I processed as`
imggray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
imgBlur=cv2.GaussianBlur(imggray,(5,5), 0)
imgDil=cv2.dilate(imgBlur,np.ones((5,5),np.uint8),iterations=1)
imgEro=cv2.erode(imgDil,np.ones((5,5),np.uint8),iterations=2)
ret,imgthresh=cv2.threshold(imgEro,28,255, cv2.THRESH_BINARY )
And for this Image as
imggray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
imgBlur=cv2.GaussianBlur(imggray,(5,5), 0)
imgDil=cv2.dilate(imgBlur,np.ones((5,5),np.uint8),iterations=0)
imgEro=cv2.erode(imgDil,np.ones((5,5),np.uint8),iterations=0)
ret,imgthresh=cv2.threshold(imgEro,37,255, cv2.THRESH_BINARY )
I had to change the value of iterations and the minimum threshold to obtain proper results. What can be the solution so I should not change the values?

Is there a way to ignore EXIF orientation data when loading an image with PIL?

I'm getting some unwanted rotation when loading images using PIL. I'm loading image samples and their binary mask, so this is causing issues. I'm attempting to convert the code to use openCV instead, but this is proving sticky. I haven't seen any arguments in the documentation under Image.load(), but I'm hoping there's a workaround I just haven't found...
There is, but I haven't written it all up. Basically, if you load an image with EXIF "Orientation" field set, you can get that parameter.
First, a quick test using this image from the PIL GitHub source Pillow-7.1.2/Tests/images/hopper_orientation_6.jpg and run jhead on it you can see the EXIF orientation is 6:
jhead /Users/mark/StackOverflow/PillowBuild/Pillow-7.1.2/Tests/images/hopper_orientation_6.jpg
File name : /Users/mark/StackOverflow/PillowBuild/Pillow-7.1.2/Tests/images/hopper_orientation_6.jpg
File size : 4951 bytes
File date : 2020:04:24 14:00:09
Resolution : 128 x 128
Orientation : rotate 90 <--- see here
JPEG Quality : 75
Now do that in PIL:
from PIL import Image
# Load that image
im = Image.open('/Users/mark/StackOverflow/PillowBuild/Pillow-7.1.2/Tests/images/hopper_orientation_6.jpg')
# Get all EXIF data
e = im.getexif()
# Specifically get orientation
e.get(0x0112)
# prints 6
Now click on the source and you can work out how your image has been rotated and undo it.
Or, you could be completely unprofessional ;-) and create a function called SneakilyRemoveOrientationWhileNooneIsLooking(filename) and shell out (subprocess) to exiftool and remove the orientation with:
exiftool -Orientation= image.jpg
Author's "much simpler solution" detailed in above comment is misleading so I just wanna clear that up.
Pillow does not automatically apply EXIF orientation transformation when reading an image. However, it has a method to do so: PIL.ImageOps.exif_transpose(image)
OpenCV automatically applies EXIF orientation when reading an image. You can disable this behavior by using the IMREAD_IGNORE_ORIENTATION flag.
I believe the author's true intention was to apply the EXIF orientation rather than ignore it, which is exactly what his solution accomplished.

Base64 signature capture as black square box in Codenameone App

I'm using Signature capture in Mobile App and most of the time it works correct. I have offline capability for the App s o when the App is in offline mode, signature is captured and while sending to the server the image is going as black square.This is due to any data corruption at the mobile level or any issue in using the signature API. Please advise.
Code:
Image sourceImage = sign.getSignatureImage().scaledSmallerRatio(300, 100);
Image mute = Image.createImage(sourceImage.getWidth(), sourceImage.getHeight(), 0xffffffff);
Graphics g = mute.getGraphics();
g.drawImage(sourceImage, 0, 0);
test.setSignature(mute);
Base64.encodeNoNewline(EncodedImage.createFromImage(test.getSignature(),
false).getImageData())
Questions:
New Code leads to white spaces in the signature also. Signature looks like not renderingly properly. Please advise.
What is the code if I have to send the image as PNG to the server. I'm using following code:
Base64.encodeNoNewline(EncodedImage.createFromImage(act.getSignature(),
false).getImageData())
Make sure you are saving the image file as a PNG and not as a JPEG. The image file might contain transparency and some JPEG encoders might fail in that case.
To make the image "jpegable" (totally made that up right now) you can do the following:
// white mutable image
Image mute = Image.create(sourceImage.getWidth(), sourceImage.getHeight, 0xffffffff);
Graphics g = mute.getGraphics();
g.setAntiAliased(true);
g.drawImage(sourceImage, 0, 0);
Now you can save mute as a JPEG since it's an opaque white image. The black signature will appear correctly on top of that.

How to stream depth image from a basic ToF camera module with Point Cloud Library(PCL)

Inforamtion:
I have a simple ToF(Time of Flight) camera module provided by a vendor that only contains a Depth Node.
I've already setup the PCL environment and can compile and execute the sample code it provides.
The ToF camera module comes with a source code shows how to get depth raw data(the x, y, z value) from the hard device, but doesn't tell how to stream it as both point cloud image and depth image.
Win 7 64bit, Visual Studio 2008, PCL all-in-one 32bit.
As a result, I plan to use PCL to show the Point cloud image and depth image with the x, y, z data I can get from that camera module, further more, if streaming is possible.
However, as far as I know right now is that PCL tends to store all the point cloud data as a .pcd file, and then reads it thus output a point cloud image and a depth image.
It is obviously too slow to do the streaming in such way if I have to savePCD() and readPCD() every time in each frame. So I studied the "openni grabber" and "openni range image visualization" sample code and tried execute them, sadly "No device connected." is all I got.
I have a few ideas to ask for advises before I try:
Is there a way to use Openni on a device except Kinect, Xtion and PrimeSense? Even if it's just a device with no name and only has a depth node?
Can PCL show point cloud image and depth image without accessing a .pcd file? In other words, can I just assign the value of each vertex and construct a image?
Can I just normalize all the vertices and construct a image with barely Opencv?
Is there any other method to stream that ToF camera module in point cloud image and depth image?
1) Changing the OpenNI grabber to use your own ToF camera will be much more work than to just use the example from the camera in a loop shown below.
2) Yes PCL can show point cloud image and depth without accessing a .pcd file. What the .pcd loader does is to parse the pcd-file and place the values in the cloud format. You can do this directly from your camera data as shown below.
3) No idea what you mean here. I propose you try to use the pcl visualizer or cloud viewer as proposed below.
You can do something like:
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
cloud->isDense = true;
cloud->width = widthOfTOFsensor;
cloud->height = heightOfTOFsensor;
cloud->size = cloud->width * cloud->height;
//Create some loop
//grabNewFrame from TOFsensor
for(int pointIndex=0;pointIndex<cloud->size();pointIndex++)
{
cloud->points[pointIndex].x = tofSensorData[pointIndex].x; //Don't know the tofData format, so I just guessed something.
cloud->points[pointIndex].y = tofSensorData[pointIndex].y;
cloud->points[pointIndex].z = tofSensorData[pointIndex].z;
}
// Plot the data using pcl visualizer or cloud viewer, see:
http://pointclouds.org/documentation/tutorials/cloud_viewer.php#cloud-viewer
http://pointclouds.org/documentation/tutorials/pcl_visualizer.php#pcl-visualizer

Resources