Smooth Operation In Image Processing - c

I would like to optimize my code,
My code contains following steps
//img size 1024 X 720
cvSmooth(img, inputImg, CV_GAUSSIAN, 5, 0, 0);
FilterOperations::sobelSchaar(inputImg, sobImg);
cvResize(sobImg, sob2Img);
//sob2Img size 512 X 360
cvSmooth(sob2Img, sob2Img, CV_GAUSSIAN, 3, 3);
imgProceObj.normalise(sob2Img);
cvAdaptiveThreshold(sob2Img, sob2Img, 255,
CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, 31, 50);
How can I optimize above code, without changing final result ?

pyrDown() might be doing both required steps in one go.

Related

Arduino Binary Array is too Large

I have a three-dimensional array of binary numbers, which I use as a dictionary and pass through an LED array. The dictionary covers 27 letters, and each letter covers 30x30 pixels (where each pixel is a 0 or a 1).
I was using the Intel Edison - and the code worked well - but I ditched the Edison after having trouble connecting it to my PC (despite replacing it once). I switched to the Arduino Uno, but am now receiving an error that the array is too large.
Right now I have the array set as boolean. Is there anyway to reduce the memory demands of the array by setting it instead as bits? The array consists of just zeros and ones.
Here's a snip of the code:
boolean PHDict[27][30][30] = {
/* A */ {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* this is one column of thirty, that show "A" as a letter */
You could write it as
#include <stdint.h>
//...
uint32_t PHdict[27][30] = {
{ 0x00004000, ... },
....
};
.. Where each entry contains 30 bits packed into a 32-bit number.
The size is under 4k bytes.
You would need a bit of code to unpack the bits when reading the array, and a way to generate the packed values (I.e a program which runs on your "host" computer, and generates the initialized array for the source code)
For the AVR processor, there's also a way to tell the compiler you want the array stored in PM (Flash memory) instead of DM - I think if you have it in DM, the compiler will need to put the initialization data in PM anyway, and copy it over before the program starts, so it's a good idea to explicitly store it in PM. See https://gcc.gnu.org/onlinedocs/gcc/AVR-Variable-Attributes.html#AVR-Variable-Attributes
In fact, depending on the amount of flash memory in the processor, changing it to PM may be sufficient to solve the problem, without needing to pack the bits.

Opencv 2.4.0: Load image through unsigned char array

I think I've thoroughly searched the forums, unless I left out certain keywords in my search string, so forgive me if I've missed a post. I am currently using OpenCV 2.4.0 and I have what I think is just a simple problem:
I am trying to take in an unsigned character array (8 bit, 3 channel) that I get from another API and put that into an OpenCV matrix to then view it. However, all that displays is an image of the correct size but a completely uniform gray. This is the same color you see when you specify the incorrect Mat name to be displayed.
Have consulted:
Convert a string of bytes to cv::mat (uses a string inside of array) and
opencv create mat from camera data (what I thought was a BINGO!, but can't seem to get to display the image properly).
I took a step back and just tried making a sample array (to eliminate the other part that supplies this array):
int main() {
bool isCamera = true;
unsigned char image_data[] = {255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255};
cv::Mat image_as_mat(Size(6,3),CV_8UC3,image_data);
namedWindow("DisplayVector2",CV_WINDOW_AUTOSIZE);
imshow("DisplayVector2",image_as_mat);
cout << image_as_mat << endl;
getchar();
}
So I am just creating a 6x3 matrix, with the first row being red pixels, the second row being green pixels, and third row being blue. However this still results in the same blank gray image but of correct size.
The output of the matrix is (note the semicolons i.e. it formatted it correctly):
[255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0; 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0; 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255]
I might be crazy or missing something obvious here. Do I need to initialize something in the Mat to allow it to display properly? Much appreciated as always for all your help everyone!
all the voodoo here boils down to calling getchar() instead of (the required) waitKey()
let me explain, waitKey might be a misnomer here, but you actually need it, as the code inside wraps the window's messageloop, which triggers the actual blitting (besides waiting for keypresses).
if you don't call it, your window will never get updated, and will just stay grey ( that's what you observe here )
indeed, you should have trusted the result from cout , your Mat got properly constructed, it just did not show up in the namedWindow
(btw, getchar() waits for a keypress from the console window, not your img-window)
hope it helps, happy hacking further on ;)

Wrong output with OpenCV Distance Transform

I am trying to find the Distance Transform for each pixels of a binary image, using OpenCV library for C. According to the rule of DT, the value of each zero (black) pixels should be 0. And that of 255 (white) pixels should be the shortest distance to a zero (black) pixel, after applying Distance transform.
I post the code here.
IplImage *im = cvLoadImage("black_white.jpg", CV_LOAD_IMAGE_GRAYSCALE);
IplImage *tmp = cvCreateImage(cvGetSize(im), 32, 1);
cvThreshold(im, im, 128, 255, CV_THRESH_BINARY_INV);
//cvSaveImage("out.jpg", im);
cvDistTransform(im, tmp, CV_DIST_L1, 3, 0, 0 );
d = (uchar*)tmp->imageData;
da = (uchar*)im->imageData;
for(i=0;i<tmp->height;i++)
for(j=0;j<tmp->width;j++)
{
//if((int)da[i*im->widthStep + j] == 255)
fprintf(f, "pixel value = %d DT = %d\n", (int)da[i*im->widthStep + j], (int)d[i*tmp->widthStep + j]);
}
cvShowImage("H", tmp);
cvWaitKey(0);
cvDestroyWindow("H");
fclose(f);
I write the pixels values along with their DT values to a file. As it turns out, some of the 0 pixels have DT values like 65, 128 etc. ie they are not 0. Moreover, I also have some white pixels that have DT values as 0 (which I guess, souldn't happen as it should be atleast 1).
Any kind of help will be appreciated.
Thanks in advance.
I guess it is because of CV_THRESH_BINARY_INV which inverts your image. So the areas you expect to be white are in fact black for DT.
Of cause, inverting the image may be your intention. Display the image im and compare with tmp for verification

Increase the intensity of certain part of frame using opencv

Suppose there is a frame with some image.I want to display only those parts which have pixel intensity above 120 or 130. How can I do that with OpenCv ? Is there any commands to do so?
Then i need to set those parts to some intensity of 190.
As mentioned by astay13, you can use the threshold function like this:
Mat image = imread("someimage.jpg", 0); // flag == 0 means read as grayscale
Mat mask;
// this tells you where locations >= 120 pixel intensity are
threshold(image, mask, 120.0, 255.0, THRESH_BINARY);
// this sets those locations to 190 based on the mask you just created
image.setTo(Scalar(190, 0, 0), mask);
imshow("image", image);
Hope that is helpful!
You could try the cvThreshold function. For the second part, cvFloodFill might be what you need.

gdk_pixbuf_composite usage

I have two png images First one with Width1 2247 Height1 190 and second one with Width2 155 Height2 36. I wan't the second image(src) to be placed in the center of first image(dest). I created pixel buf of both and used gdk_pixbuf_composite as follows.
gdk_pixbuf_composite( srcpixbuf, dstpixbuf, 1000, 100, width2, height2, 0, 0, 1, 1, GDK_INTERP_BILINEAR, 255);
I get a hazy window of width2 and height2 on the first image.
If I replace width2 and height2 with 1.0 then I don't get the srcimage on the dstimage. Where am I going wrong?
gdk_pixbuf_composite( srcpixbuf, dstpixbuf, 1000, 100, width2, height2, 1000, 100, 1, 1, GDK_INTERP_BILINEAR, 255);
This solved. Wrongly understood the offset parameter. Basically an intermediate scaled image is created and only the part represented by the dest wid, height is composited. So in my case we need to move the entire unscaled image to the destination offset which is done by the offset parameter.

Resources