Ask Your Question

Guyygarty's profile - activity

2019-08-07 09:56:14 -0600 received badge  Notable Question (source)
2019-06-20 22:42:10 -0600 received badge  Nice Answer (source)
2019-02-28 09:31:35 -0600 received badge  Popular Question (source)
2019-01-21 21:23:24 -0600 received badge  Good Answer (source)
2018-07-21 02:16:52 -0600 received badge  Popular Question (source)
2018-01-24 11:05:30 -0600 received badge  Nice Answer (source)
2017-12-29 02:07:23 -0600 received badge  Enlightened (source)
2017-12-27 08:37:01 -0600 commented answer c++ windows forms /CLR

see here

2017-12-27 08:35:21 -0600 commented answer GUI for OpenCv with visual studio

I try to avoid having any code (other than the main form constructor) in the .h file. The code above goes in MyForm.cpp

2017-08-01 07:50:47 -0600 received badge  Good Answer (source)
2017-03-03 08:58:10 -0600 answered a question transform 16bit grayscale to RGB with constants

If I understand correctly, you have a 16 bit image, I, and want to "tint it" so that R= a*I/255, G=b*I/255, G=c*I/255. What you could do is to use:

   I.convertTo(R, CV_8UC1, a/255, 0);
   I.convertTo(G, CV_8UC1, b/255, 0);
   I.convertTo(B, CV_8UC1, c/255, 0);

and then merge R,G, B into a color image

std::vector<cv::Mat> array_to_merge;
array_to_merge.push_back(B);
array_to_merge.push_back(G);
array_to_merge.push_back(R);
cv::merge(array_to_merge, Dest);

Do not use pixel operations if you can avoid them.

guy

2017-02-17 14:00:39 -0600 answered a question Showing gray image in picturebox in Visual studio c++

I have not tried to put a grayscale image directly into the picturebox but rather converted the gray image to an RGB image and then put that. something like:

cvtColor(GrayImage, ColorImage, CV_GRAY2RGB, 3);
 System::Drawing::Bitmap^ BitmapToDisplay=gcnew System::Drawing::Bitmap(ColorImage.cols, ColorImage.rows, (int)ColorImage.step, System::Drawing::Imaging::PixelFormat::Format24bppRgb, ColorImage.ptr());

guy

2016-11-29 13:42:27 -0600 commented answer OpenCV IDE for developemnt

sorry for the delay: here

2016-11-21 16:47:41 -0600 commented question compare the size of two contours

if you are interested in the length of the contour, you can use your factors but if you are interested in the area you should square them

  • In the first image 5mm/pixel --> The area of each pixel is 5x5=25

  • In the second image 8.71 mm/pixel --> the area of each pixel is 8.71 x 8.71=75.9

2016-10-04 10:42:07 -0600 answered a question detect all range colors on image

Hi,

Do you need the actual pixel coordinates or just the number of pixels?

If the latter you would probably be better off using calcHist to generate a histogram of the hue value. See example here:

http://docs.opencv.org/2.4/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.html

guy

2016-09-26 07:38:15 -0600 answered a question Error when get color from pixel in visual studio C++

Looks to me like you are trying to access a point outside your Mat.

You need to explicitly check that the values of x and y are smaller than src.cols and src.rows respectively before calling at.

OpenCV checks this internally but throws an exception if they are not.

guy

2016-09-16 20:58:31 -0600 answered a question Accessing pixel intensity values 16 unsigned char

I don't use floats but that seems like the right way to me. For 16 bit I use at<unsigned __int16>(y,x) or at<__int16>(y, x).

guy

2016-09-10 06:37:05 -0600 commented answer How to pass values to main function (vs2015,opencv,c++)

Does the program crash before the first cout?

if not, what does the program think the values of argc and argv[1] are?

guy

2016-09-09 06:04:36 -0600 received badge  Nice Answer (source)
2016-09-08 15:04:12 -0600 commented answer GUI for OpenCv with visual studio

you can just write the OpenCV code into the GUI control's callback function. I'll add an example to the answer, as there is no room in comments.

2016-09-08 12:27:18 -0600 answered a question How to pass values to main function (vs2015,opencv,c++)

Go to the project properties and enter the arguments under "Debugging > Command Arguments"

image description

guy

2016-05-25 11:40:32 -0600 answered a question Watershed not segmenting correctly

I think I found the problem.

I was passing a binary image instead of a grayscale one to watershed. Fixing this seems to have almost solved my problem. I still get the background merged with one of the blobs, although it's not the last one anymore.

guy

2016-05-23 15:16:54 -0600 asked a question Watershed not segmenting correctly

Hi,

I am trying to implement a watershed segmentation to separate touching blobs. I want to separate the blobs from each other but I am getting a separation of the blobs from each other and from the background. In my final segmented image, each blob has a halo like this, instead of just being an isolated blob:

Original Image:

image description

Segmented image:

image description

What am I doing wrong?

Here is the code I am using:

    System::Void Watershed(Mat DAPI, Mat DAPIBin, int Param)
{
    imwrite("Bin.tif", DAPIBin);
    Mat dist_8u;
    Mat dist(DAPIBin.size(), CV_32F);
    if (Param > 0)
    {
        distanceTransform(DAPIBin, dist, CV_DIST_L2, CV_DIST_MASK_PRECISE);
        dist_8u = (dist > Param);
    }
    imwrite("dist_8u.tif", dist_8u);
    // Find total markers
        std::vector<std::vector<cv::Point> > contours;
        cv::findContours(dist_8u, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
        //Total objects
        int ncomp = (int) contours.size();
        Mat markers = cv::Mat::zeros(dist.size(), CV_32SC1);
        Mat in[] = {dist_8u,dist_8u,dist_8u};
        Mat D3ch;
        cv::merge(in, 3, D3ch);
        for (int i = 0; i < ncomp; i++)
        {
            drawContours(markers, contours, i, cv::Scalar::all(i + 1), -1);
        }

        imwrite("Markers.tif", markers);
        cv::watershed(D3ch, markers);
        Mat Mask=markers>0;
        erode(Mask,Mask,Mat());
        imwrite("mask.tif", Mask);
        if (ncomp > 0)
            DAPIBin=DAPIBin.mul(Mask);
        imwrite("Final.tif", DAPIBin);
}

And the intermediate images:

image description image description image description

guy

Edit: Some more info:

Here is a side by side view of the Markers image before and after the watershed.

image description

After the watershed, the last marker (the one cropped by the top of the image, and which was marker #ncomp) has expanded to fill all area not taken up by other markers. The black outlines in the post-watershed image follow the contours of the pre-watershed markers exactly.

guy

2016-05-20 12:51:00 -0600 commented question mat transpose .t() a Nx2 mat gives me a 1x2N output.

How many channels does your Mat have? are you sure it is an Nx2 Mat and not a n Nx1 mat with two channels?
Both should print as N rows of 2 using cout. but when you transpose, the first will print as two rows of N and the second will probably print as a row of 2N. guy

2016-05-12 12:19:16 -0600 commented answer c++ windows forms /CLR

I add the opencv .h files in the .cpp file for the form and not in the header. I try to not have any code at all (other than the form constructor and destructor) in the header.

2016-04-25 13:18:21 -0600 answered a question opencv with windows form application (Visual Studio 13 GUI) c++

I usually start with a windows form application and add the openCV code in the callback functions. The form header just has the declarations for the form callbacks with the code in the associated cpp file. This is not the default for visual c++ but is the "proper" way to do things in C.

Within the header I do not include any OpenCV elements. I put the

    #include "opencv2\opencv.hpp"
    #include "opencv2\highgui\highgui.hpp"
    #include "opencv2\imgproc\imgproc.hpp"
...
    using namespace cv;

at the top of the .cpp file. all Mat's are declared internally in the callback or as global variables at the .cpp level. in the project properties make sure to:

  • Add $(OPENCV_DIR)....\include to C/C++ -> General -> Additional Include Directories
  • Add $(OPENCV_DIR)\lib to Linker->General->Additional Library Directories
  • Add opencv_core249d.lib and any other libraries you are using to Linker->Input->Additional Dependancies (replace 249 with the version you are using, the d denotes to use the debug version of the libraries and can be ommitted.)

This works well for me.

guy

2016-04-25 12:02:37 -0600 commented question opencv with windows form application (Visual Studio 13 GUI) c++

Can you get a windows form application to work without OpenCV? guy

2016-04-05 13:05:08 -0600 answered a question GUI for OpenCv with visual studio

Visual studio provides tools to make forms in C++ but, starting with VS2012, they have made it difficult - they want you to make forms in C#, or VB not in C++.

A good tutorial on how to make a windows forms application using Visual C++ 2013 is given here

Basically you need your application to be a CLR application, rather than a console. You can then add GUI forms to it and call OpenCV from them. I have written several such applications and can help if you have more specific questions on interfacing OpenCV with CLR forms.

guy

Edit

Here is an example. The form frmImaging has a buttons called cmdLoad and cmdSave and a textbox txtFileName. In the associated cpp file I have:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

cv::Mat image //global mat file for storing the image. It is accessible by all GUI callbacks in this file. 

//callback for cmdLoad button - loads image into Mat
System::Void frmImaging::cmdLoad_Click(System::Object^  sender, System::EventArgs^  e) 
{
//Get filename
    if(System::String::IsNullOrEmpty(openFileDialog1->InitialDirectory))
        openFileDialog1->InitialDirectory=txtDir->Text;

    if( openFileDialog1->ShowDialog()!=::DialogResult::OK)
        return;

    txtFilename->Text=openFileDialog1->FileName;
    char FileName[200];
    sprintf(FileName,"%s",openFileDialog1->FileName);

//load image    
    image=imread(FileName,CV_LOAD_IMAGE_ANYDEPTH);
//display image 
        imshow("Display Window",image);
 }

//callback of cmdSave button - save image
System::Void frmImaging::cmdSave_Click(System::Object^  sender, System::EventArgs^  e) 
{
        // get filename from GUI
    char FileName[200];
    sprintf(FileName,"%s",txtFilename->Text);


    imwrite(FileName, image);

}
2016-04-05 09:24:17 -0600 commented question Displaying image results in real time

@StevenPuttemans: What would be the "correct" way to rapidly throw images on the screen in the final application (managed Visual C++)?

My application works and was profiled and imshow/waitkey(1) is a bottleneck...

2016-03-31 20:54:29 -0600 commented answer find all the colors of a given image and their pixel position

I'm sure @berak 's answer will do the trick for you, I was not familiar with the partition function.

One small concern I have is that, per the documentation, the partition function is O(N^2) where I guess N would be the number of pixels in your image. My solution can be tweaked to run in linear time WRT the number of pixels. There will probably, be a (very) large overhead for memory allocation and initialization. so if you're not working with huge images I would try Berak's solution before mine.

The problem I see with @Tetragramm 's solution is that there is no easy way to decide if the color of the pixel you are looking at was seen before, without checking a long list of color values one by one. You would probably want to figure out some way to sort the list of colors.

guy

2016-03-30 12:35:03 -0600 answered a question find all the colors of a given image and their pixel position

Unless you have a >16 MegaPixel image, this is probably one of the rare occasions where looping over all pixels and performing pixel-wise operations would be the fastest. Here's how I would do it (trying to minimize required storage, even so this requires quite a lot):

You would need

  • a 256x256x256 Mat Let's call it Colors (you may be able to use a SparseMat for this and should if you can)
  • a Mat the size of your original image, lets call it Next

The type of both Mats should be CV_32SC1. You could get away with a CV_16UC1 if the original image is <256x256. Both Mats initialized with all zeros.

What you then do is cycle through the pixels.


For each pixel:

Calculate its index=X+Y*width+1

It's color values are R, G, B.

If the value of the Colors Mat at location (R,G,B) is zero set it to index and go to next pixel

if it is not zero (say it is p), go to position p in the Next mat. If that is zero, set it to index and continue. if not zero, repeat the last step as many times as is required to get to zero, then set that zero to index


Finally, to get all the pixel values of a certain color, you would find the corresponding pixel in Colors, if it is zero there are no such pixels, if it is a value index!=0, that is the index of the first pixel of that color. You then cycle through the Next matrix starting with position index, the value of that position is the index of the second pixel and so on, until you get to index==0.

Good luck

guy

2016-03-30 10:03:04 -0600 answered a question why they are going for more channels in image processing?

Another example:

In fluorescence microscopy, you can get up to 6 different colors corresponding to different dyes used to stain your specimen. I believe 6 is the maximum with a standard (i.e. not hyperspectral) microscope.

For example here are some pictures of an irradiated human chromosome, where different regions are painted with different dyes. The order of bands indicates damage to the chromosome. image description

guy

2016-03-16 13:33:14 -0600 answered a question Is it poosible to make OpenCV read multiple page tiff

Re external libraries, that would depend on your OS and compiler. Using Microsoft Visual C++ you can use a TiffBitmapDecoder object. The code below may be overly complicated but it should work.

Stream^ imageStreamSource = gcnew FileStream(FileName, FileMode::Open, FileAccess::Read, FileShare::Read);
TiffBitmapDecoder^ decoder = gcnew TiffBitmapDecoder(imageStreamSource, BitmapCreateOptions::PreservePixelFormat, BitmapCacheOption::Default);
BitmapSource^ bitmapSource = decoder->Frames[FrameNumber];
int width=bitmapSource->PixelWidth;
int height=bitmapSource->PixelHeight;
int bitsPerPixel=bitmapSource->Format.BitsPerPixel; 
Type=;//you'll need to figure this one out
int stride = (width * bitsPerPixel + 7) / 8;//this may need to change for color images
array<System::Byte>^ pixels = gcnew array<System::Byte>(height * stride);
bitmapSource->CopyPixels(pixels,stride,0);
Mat Img=Mat(Height,Width,Type,&pixels[0],Stride);

guy

2016-03-12 14:40:39 -0600 commented question Reading pixel values from a binary file

You may also want to multiply img by 16 to get 0x0000 1111 1111 1111 to display as white.

2016-03-12 14:35:03 -0600 commented question Reading pixel values from a binary file

There seems to be some mismatch with the size of your buffers:

The image is 128x128x4 =65536 bytes

you load it into an unsigned int buffer with double that size (I believe an unsigned int is 16 bit, and you have 65536 of them). At this point each pixel takes up TWO 16 bit ints.

You then load into a signed 16 bit Mat. Each pixel in the original image is now on two pixels in the Mat.

The fact that the Mat is signed while the data isn't will probably turn your blacks to 50% Gray. Your whites may be dim because you are displaying a 12 bit image when OpenCV is expecting 16 bits and probably scales brightness accordingly.

I think LBerger's solution will work better for you with the following changes:

  • change buffer to unsigned char - just for neatness
  • change img to CV_32U
2016-02-27 22:24:36 -0600 answered a question Intersection of a contour and line in OpenCV c++?

Your life may be easier if the line corresponded to a row of the image. That way you just do:

drawContours( drawing1, contours, i, Scalar(255,0,0), -2, 8, hierarchy, 0, Point() );//note that thickness is negative - that fills the contour.
if (countNonZero(Drawing1.row(300))>0)
{
//car #i is crossing row 300
}

The problem with this type of algorithm is that you would need to keep track that you don't count the same car in the next frame.

If only one car at a time can cross the line, you would just need some sort of flag that only allows the counter to increment if there weren't any lit pixels on the line in the previous frame. If multiple cars can cross the line simultaneously, you will need to correlate between car i in one frame and car j in the other. This is much harder

If the cars are relatively slow you could just look at the blob centroids and find the nearest one in the previous frame or maybe one that has moved in a predefined direction. If they are fast (i.e. motion between frames is larger than average distance between cars) you may need a more complex algorithm.

guy