i'm working on a VC++ and OpenCV application, i'm loading images into picturBox and make some OpenCV operations on them, i assign the loaded image into IplImage to make processing on it but then assign the processed image again into the picture box, i write this code to load the image selected from openFileDialog into IplImage ,binarize the image then reassign the binarized image back to the pictureBox
code:
const char* fileName = (const char*)(void*)
Marshal::StringToHGlobalAnsi(openFileDialog1->FileName);
IplImage *img=cvLoadImage(fileName,CV_LOAD_IMAGE_COLOR);
int width=img->width;
int height=img->height;
IplImage *grayScaledImage=cvCreateImage(cvSize(width,height),IPL_DEPTH_8U,1);
cvCvtColor(img,grayScaledImage,CV_RGB2GRAY);
cvThreshold(grayScaledImage,grayScaledImage,128,256,CV_THRESH_BINARY);
this->pictureBox1->Image=(gcnew
System::Drawing::Bitmap(grayScaledImage->width,grayScaledImage->height,grayScaledImage->widthStep,
System::Drawing::Imaging::PixelFormat::Format24bppRgb,(System::IntPtr)grayScaledImage->imageData));
but i doesn't find a format which displays a binary image, any help about that.
Original Image:
Converted image:
You seem to be creating an RGB image (System::Drawing::Imaging::PixelFormat::Format24bppRgb) but copying into it a grayscale, presumably the System::Drawing::Imaging function doesn't do conversion - or isn't doing it properly.
Edit: Some more explanation.
Your greyscale image is stored in memory as one byte for each pixel Y0, Y1, Y2,Y3...... Y639 (we use Y for brightness, and assuming a 640 pixel wide image).
You have told the .net image class that this is Format24bppRgb which would be stored as one red,one green and blue byte per pixel (3bytes = 24bpp). So the class takes your image data and assumes that Y0,Y1,Y2 are the red,green,blue values for he first pixel, Y3,Y4,Y5 for the next and so on.
This is using up 3x as many bytes as your image has, so after 1/3 of the row it starts reading the next row and so on - which gives you the three repeated pictures.
ps. the fact that you have turned it into a binary image just means that the Y values are either 0 or 255 - it doesn't change the data size or shape.
Related
I trained an image classification neural network model written in ml5.js. When I try to use the model files in a p5.js web editor, I get an error 'Based on the provided shape, [1,64,64,4], the tensor should have 16384 values but has 20155392'.
The code is in this p5 sketch - https://editor.p5js.org/konstantina1/sketches/85Ny1SC2J (clicking on the arrow in the top right corner will show the files).
When I run a local server on a web page with the same structure, I see 'model ready!' (a confirmation that the model has loaded) and that's it.
I read a lot of comments that the bin file may be corrupt - I saved the model myself producing the bin file so it should be ok.
As suggested here by the author of very similar code, https://www.youtube.com/watch?v=3MqJzMvHE3E, adding pixelDensity(1) in setup() doesn't help.
I am new to machine learning, could someone please help? Thank you in advance.
The model was trained with images 64x64 px so the input test image must be the same size.
1944 (original image width) * 2592 (original image height) * 4 (number of channels) = 20155392. The tensor should have 64 (image width) * 64 (image height) * 4 (number of channels) = 16387 values. This is what the error refers to.
The copy() method used originally didn't resize the input image properly.
The correct way to resize the image is inputImage.resize(IMAGE_WIDTH, IMAGE_HEIGHT).
Working sketch: https://editor.p5js.org/konstantina1/sketches/85Ny1SC2J
A version of the sketch with image file upload: https://editor.p5js.org/konstantina1/sketches/qMNkkkbIm
I'm working on a server/client communication in node js.
Every second, the server send an image (taking by a camera) to the client.
The message structure contains among other things:
BufferX : the width of the image
BufferY : the height of the image
BufferImage : Bytes array containing pixel
The problem is: I would like to convert this buffer to an image and save it.
At first I try this:
let array = new Uint8Array(BufferImage );
fs.writeFileSync("data.png",array)
But the image isn't readable because the buffer only contains raw pixels data.
I've copy past the buffer to a python script, convert to a numpy array and reshape it. The image is correct so I'm sure that the ImageBuffer contains the correct value.
So is it possible to convert a raw pixel buffer to an image ?
Have you tried:
let array = new Uint8Array(BufferImage);
fs.writeFileSync("data.png", Buffer.from(array).toString('base64'))
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 any possibility to read the image from the picture box in vc++ using opencv imread?
am using the following code,
vector< Mat > vImg;
Mat rImg;
vImg.push_back(imread(pictureBox1->Image));
vImg.push_back(imread(pictureBox2->Image));
Stitcher stitcher = Stitcher::createDefault();
stitcher.stitch(vImg, rImg);
but am getting error
What you should do is initialize the Mat object from the PictureBox pixel data directly.
1) Here is an example and short explanation of how to create a Mat object from memory buffer
2) Here you can see how to access the pixel memory of the PictureBox, it is better to use LockBits to obtain the pointer to the memory and pass that in the constructor, but if you are new to all this you can also get it pixel by pixel.
I have a winform application in which there is a pictureBox what displays a pretty big image (2550by4500). This bitmap image is transformed from a byte array using unsafe pointer, like this:
Bitmap img;
unsafe
{
fixed (Byte* intPtr = &outBuffer[0])
img = new Bitmap(_width, _height, _width * 3, System.Drawing.Imaging.PixelFormat.Format24bppRgb, new IntPtr(intPtr));
}
So far, no problems. After displaying the image, I saved the pixel values into a Matlab .mat file using this DLL (http://www.mathworks.com/matlabcentral/fileexchange/16319). Still, no problem with saving.
However, the image in the pictureBox became like a noisy black-white image, the original image was completely lost.
Things I tried:
added the Bitmap in watch window, found out pixel values all changed. Bitmap is corrupted.
do that unsafe transformation again everytime after saving, however, it brings another problem: "AccessViolationException in Drawing.dll".
Something must have to do with the .mat saving part, because if I skip saving, no problem at all. But I do not know how they are related, memory? I tried a smaller size image, no problem. so I'm assuming that "save .mat" process corrupted the Bitmap?
Any idea would be helpful! Thank you