Processing an IplImage(OpenCV) data in Tesseract - opencv

I need to process images which i get from OpenCV.
I wrote so far:
IplImage* img=0;
img=cvLoadImage("paket2.tif");
api.SetRectangle(0,0,img->width, img->height);
api.SetImage((uchar*)img->imageData,img->width,img->height,img->depth/8,img->width*(img->depth/8));
//i tried also below line
//api.SetImage((uchar*)img->imageData,img->width,img->height,img->depth/8,img->widthStep);
int left,top,right,bottom;
left=0;top=0;right=0;bottom=0;
api.Recognize(NULL);
tesseract::ResultIterator *ri=api.GetIterator();
char * sonuc=(*ri).GetUTF8Text(tesseract::RIL_SYMBOL);
if((*ri).BoundingBox(tesseract::RIL_SYMBOL,&left,&top,&right,&bottom))
{printf("bb dogru\n");printf("%d,%d,%d,%d",left,top,right,bottom);}
printf("sonuc:%s",sonuc);
if i pass IplImage->widthStep to bytes perline, i have "wrong" boundingBox in left and right values and can not read all the text in the image.
if i pass IplImage->width*(IplImage->depth/8), boundingBox function returns false.
I hope you have some idea.
Thanks in advance.

Copy your submatrix to a new IplImage. Create a tesseract image header with the correct info(width, height, step). Link the tesseract data pointer to the iplImage data pointer.
I can't remember how to access tesseract pointer, but for opencv is image->data.ptr

This code here worked for me:
tesseract::TessBaseAPI tess;
tess.Init(argv[0], "eng", tesseract::OEM_DEFAULT);
cv::Mat image = cv::imread("...");
tess.SetImage((uchar*)image .data, image.size().width, image.size().height, image.channels(), image.step1());
tess.Recognize(0);
const char* out = tess.GetUTF8Text();

Related

How to get BGR data and data_size from cv::Mat

I can get BGR data from Mat.data pointer, but I don't know how to calculate the data size. Could somebody help me? Thanks.
If your matrix is continuous, I'd go with cv::Mat::total()
to get the number of elements and cv::Mat::elemSize() to get the matrix element size in bytes:
Mat m;
//...
uchar* data = m.data();
auto datasize = m.total() * m.elemSize();
An alternative could be (but I'm not so sure, so double check this) to take the difference between cv::Mat::dataend and cv::Mat::datastart
auto datasize = m.dataend - m.datastart;
If your matrices are not continuous, I guess that you can still use the first method to obtain the size, but don't memcpy() that amount of bytes, because it won't be your image data.

OpenCV 2.4.3 and videoInput into Mat

I am trying to capture video into a Mat type from two or more MSFT LifeCam HD-3000s using the videoInput library, OpenCV 2.4.3, and VS2010 Express.
I followed the example at: Most efficient way to capture and send images from a webcam in a network and it worked great.
Now I want to replace the IplImage type with a c++ Mat type. I tried to follow the example at: opencv create mat from camera data
That gave me the following:
VI = new videoInput;
int CurrentCam = 0;
VI->setupDevice(CurrentCam,WIDTH,HEIGHT);
int width = VI->getWidth(CurrentCam);
int height = VI->getHeight(CurrentCam);
unsigned char* yourBuffer = new unsigned char[VI->getSize(CurrentCam)];
cvNamedWindow("test",1);
while(1)
{
VI->getPixels(CurrentCam, yourBuffer, false, true);
cv::Mat image(width, height, CV_8UC3, yourBuffer, Mat::AUTO_STEP);
imshow("test", image);
if(cvWaitKey(15)==27) break;
}
The output is a lined image (i.e., it looks like the first line is correct but the second line seems off, third correct, fourth off, etc). That suggests that either the step part is wrong or there is some difference between the IplImage type and the Mat type that I am not getting. I have tried looking at/altering all the parameters, but I can't find anything.
Hopefully, an answer will help those facing what appears to be a fairly common issue with loading an image form the videoInput library to the Mat type.
Thanks in advance!
Try
cv::Mat image(height, width, CV_8UC3, yourBuffer, Mat::AUTO_STEP);

OpenCV IplImage data to float

Is there a way to convert IplImage pointer to float pointer? Basically converting the imagedata to float.
Appreciate any help on this.
Use cvConvert(src,dst) where src is the source image and dst is the preallocated floating point image.
E.g.
dst = cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_32F,1);
cvConvert(src,dst);
// Original image gets loaded as IPL_DEPTH_8U
IplImage* colored = cvLoadImage("coins.jpg", CV_LOAD_IMAGE_UNCHANGED);
if (!colored)
{
printf("cvLoadImage failed!\n");
return;
}
// Allocate a new IPL_DEPTH_32F image with the same dimensions as the original
IplImage* img_32f = cvCreateImage(cvGetSize(colored),
IPL_DEPTH_32F,
colored->nChannels);
if (!img_32f)
{
printf("cvCreateImage failed!\n");
return;
}
cvConvertScale(colored, img_32f);
// quantization for 32bit. Without it, this img would not be displayed properly
cvScale(img_32f, img_32f, 1.0/255);
cvNamedWindow("test", CV_WINDOW_AUTOSIZE);
cvShowImage ("test", img_32f);
You can't convert the image to float by simply casting the pointer. You need to loop over every pixel and calculate the new value.
Note that most float image types assume a range of 0-1 so you need to divide each pixel by whatever you want the maximum to be.

How can i create Emgu.Cv.Image<,> from pointer

I simply want to convert an Emgu.Cv.Image<,> from a pointer, I am using the following code:
Size img = CvInvoke.cvGetSize(frame);
Image<Bgr, Byte> tImg = new Image<Bgr, byte>(img.Width, img.Height, 0, frame);
I don't know what value to give in 3rd parameter of Image<,> constructor that takes a pointer. It says Size of aligned image row in bytes what does that mean?
Note that image width has to be a multiple of 4 since some OpenCV code optimization is based on this assumption when CVImage is constructed from a memory 1D array.

OpenCV Mat to IplImage* conversion

I have a pointer to image:
IplImage *img;
which has been converted to Mat
Mat mt(img);
Then, the Mat is sent to a function that gets a reference to Mat as input void f(Mat &m);
f(mt);
Now I want to copy back the Mat data to the original image.
Do you have any suggestion?
Best
Ali
Your answer can be found in the documentation here: http://opencv.willowgarage.com/documentation/cpp/c++_cheatsheet.html
Edit:
The first half of the first code area indeed talks about the copy constructor which you already have.
The second half of the first code area answers your question. Reproduced below for clarity.
//Convert to IplImage or CvMat, no data copying
IplImage ipl_img = img;
CvMat cvmat = img; // convert cv::Mat -> CvMat
For the following case:
double algorithm(IplImage* imgin)
{
//blabla
return erg;
}
I use the following way to call the function:
cv::Mat image = cv::imread("image.bmp");
double erg = algorithm(&image.operator IplImage());
I have made some tests and how it looks the image object will manage the memory. The operator IplImage() will only construct the header for IplImage. Maybe this could be useful?
You can use this form:
Your Code:
plImage *img;
Mat mt(img);
f(mt);
Now copy back the Mat data to the original image.
img->imageData = (char *) mt.data;
You can also copy the data instead of pointer:
memcpy(mt.data, img->imageData, (mt.rows*mt.cols));
(mt.rows*mt.cols) is the size that you should use for copy all data the mt to img.
Hope I helped

Resources