i have another question. Idk what is happening buti tried to make Canny edge detector. Problem is that when i want to detect edges on simple shape like square, the program is able to detect it. But when i want to detect shapes on not very simple image program just gives me image filled by only black color. Do you guys have an idea what is going on?
I use this code below:
public Bitmap CannyEdge(Bitmap bmp)
{
Image<Gray, Byte> Cannybmp;
Image<Gray, Byte> GrayBmp;
Image<Bgr, Byte> orig = new Image<Bgr, Byte>(bmp);
Image<Bgr, Byte> imgSmooth;
Bitmap output;
imgSmooth = orig.PyrDown().PyrUp();
imgSmooth._SmoothGaussian(3);
GrayBmp = imgSmooth.Convert<Gray, byte>();
Gray grayCannyThreshold = new Gray(160.0);
Gray grayThreshLinking = new Gray(80.0);
Cannybmp = GrayBmp.Canny(grayCannyThreshold.Intensity, grayThreshLinking.Intensity);
output = Cannybmp.ToBitmap();
//int a = 5;
return output;
}
private void button1_Click(object sender, EventArgs e)
{
Bitmap bmp = new Bitmap(pictureBox1.Image);
pictureBox2.Image = CannyEdge(bmp);
}
Did you try to set your grayCannyThreshold to become lesser the value of your grayThreshLinking?
Gray grayCannyThreshold = new Gray(80.0);
Gray grayThreshLinking = new Gray(160.0);
Related
I would like to merge multiple small images to create a big image. As I have a lot of small image I would like to use threads.
OpenCV allows to select an ROI, so I would like to copy a small image in a predefined ROI.
The problem is that by using threads, the ROI changes before having had time to copy the small image into the large one.
To illustrate this problem I have the following code:
private void Test()
{
int size = 256;
//Create RGB Image
Image<Bgr, byte> R = new Image<Bgr, byte>(size, size, new Bgr(Color.Red));
Image<Bgr, byte> G = new Image<Bgr, byte>(size, size, new Bgr(Color.Green));
Image<Bgr, byte> B = new Image<Bgr, byte>(size, size, new Bgr(Color.Blue));
Image<Bgr, byte>[] imageArray = new Image<Bgr, byte>[3] { R, G, B};
Image<Bgr, byte> merger = new Image<Bgr, byte>(size * 3, size, new Bgr(Color.Black));
// Create final image with thread
Parallel.For(0, imageArray.Length, i =>
{
merger.ROI = new Rectangle(i * 256, 0, size, size);
imageArray[i].CopyTo(merger);
});
merger.ROI = Rectangle.Empty;
//Show the image
Utils.ShowImage(merger);
//Free
for (int i = 0; i < 3; i++)
imageArray[i].Dispose();
merger.Dispose();
}
I create 3 small images, one red, one green, one blue. I merge these 3 images into one to create this result:
But with threads I have the following result:
Is there a way to select multiple ROIs and keep the benefit of the threads?
I'm coding in C# and I need help with the difference between two images. I'm using the emgu to help me with this part. The problem here is that as long as there is a diff in the pixel, it will be shown in the resulted pic.
However, what I need is if the pixel for the RefImg is higher than the CompImg, the color should be red and if it is lesser it should be green.
The code should take a minimal amount of time to execute too.
The code below is what I'm using now.
Image<Bgr, Byte> RefImg = new Image<Bgr, Byte>(new Bitmap(refImg));
Image<Bgr, Byte> CompImg = new Image<Bgr, Byte>(new Bitmap(compImg));
Image<Bgr, Byte> Difference; //Difference
double Threshold = 5;
Difference = RefImg.AbsDiff(CompImg);
Difference = Difference.ThresholdBinary(new Bgr(Threshold, Threshold, Threshold), new Bgr(0, 255, 0));
Using Abs diff allow you to find différences but not the sign due to absolute value operator.
To find greater and lower pixels value you must use cmp function.
Image<Bgr, Byte> RefImg = new Image<Bgr, Byte>(...);
Image<Bgr, Byte> CompImg = new Image<Bgr, Byte>(...);
//Convert to gray levels or split channels
Image<Gray, Byte> RefImgGray = RefImg.Convert<Gray, byte>();
Image<Gray, Byte> CompImgGray = CompImg.Convert<Gray, byte>();
//Compare image and build mask
Image<Gray, Byte> MaskDifferenceHigh = RefImgGray.Cmp(CompImgGray, CmpType.GreaterThan);
Image<Gray, Byte> MaskDifferenceLow = RefImgGray.Cmp(CompImgGray, CmpType.LessThan);
//Draw result
Image<Bgr, byte> result = RefImg.CopyBlank();
result.SetValue(new Bgr(Color.Red),MaskDifferenceHigh);
result.SetValue(new Bgr(Color.Green), MaskDifferenceLow);
Hope it helps.
I am new to EmguCV and OpenCV. I want to detect the text Regions from an Image using EmguCV.
There are already some solutions posted on Stack using OpenCV.
Extracting text OpenCV
But unable to convert that OpenCV code to EmguCV.
Here is a direct conversion of the accepted answer in the link you provided into c# with EMGU. You might have to make some alterations since its a slightly different implementation but it should get you started. I also doubt it is a very robust so depending on your specific use it might not be suitable. Best of luck.
public List<Rectangle> detectLetters(Image<Bgr, Byte> img)
{
List<Rectangle> rects = new List<Rectangle>();
Image<Gray, Single> img_sobel;
Image<Gray, Byte> img_gray, img_threshold;
img_gray = img.Convert<Gray, Byte>();
img_sobel = img_gray.Sobel(1,0,3);
img_threshold = new Image<Gray, byte>(img_sobel.Size);
CvInvoke.cvThreshold(img_sobel.Convert<Gray, Byte>(), img_threshold, 0, 255, Emgu.CV.CvEnum.THRESH.CV_THRESH_OTSU);
StructuringElementEx element = new StructuringElementEx(3, 17, 1, 6, Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_RECT);
CvInvoke.cvMorphologyEx(img_threshold, img_threshold, IntPtr.Zero, element, Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_CLOSE, 1);
for (Contour<System.Drawing.Point> contours = img_threshold.FindContours(); contours != null; contours = contours.HNext)
{
if (contours.Area > 100)
{
Contour<System.Drawing.Point> contours_poly = contours.ApproxPoly(3);
rects.Add(new Rectangle(contours_poly.BoundingRectangle.X, contours_poly.BoundingRectangle.Y, contours_poly.BoundingRectangle.Width, contours_poly.BoundingRectangle.Height));
}
}
return rects;
}
Usage:
Image<Bgr, Byte> img = new Image<Bgr, Byte>("VfDfJ.png");
List<Rectangle> rects = detectLetters(img);
for (int i=0;i<rects.Count();i++)
img.Draw(rects.ElementAt<Rectangle>(i),new Bgr(0,255,0),3);
CvInvoke.cvShowImage("Display", img.Ptr);
CvInvoke.cvWaitKey(0);
CvInvoke.cvDestroyWindow("Display");
i have a blood image and i applied watershed on it .. its works and determines the cells but i don't know how to put each cell in a separate image .. i'm working with emgu.cv can i get some help
here i segment the picture using my watershed method and then put the marker on the original image
Image<Gray, Int32> boundaryImage = watershedSegmenter.Process(image);
Image<Gray, Byte> test = watershedSegmenter.GetWatersheds(); Image<Bgr, byte>dest=new Image<Bgr, byte>(image.Width, image.Height);
dest = image.And(image, test);
pictureBox1.Width = boundaryImage.ToBitmap().Width;
pictureBox1.Height = boundaryImage.ToBitmap().Height;
pictureBox1.BackgroundImage = boundaryImage.ToBitmap();
It seems like EMGUcv cvWatershed() is having some bugs which is not yet resolved. The Marker Image is always returning white image. Can you share your 1st stage output images?
I'm not able to view any images by using this code.
Image<Bgr, Byte> image = Img_Source_Bgr.Copy();
Image<Gray, Int32> marker = new Image<Gray, Int32>(image.Width, image.Height);
Rectangle rect = image.ROI;
marker.Draw(
new CircleF(
new PointF(rect.Left + rect.Width / 2.0f, rect.Top + rect.Height / 2.0f),
/*(float)(Math.Min(image.Width, image.Height) / 20.0f)*/ 5.0f),
new Gray(255),
0);
Image<Bgr, Byte> result = image.ConcateHorizontal(marker.Convert<Bgr, byte>());
Image<Gray, Byte> mask = new Image<Gray, byte>(image.Size);
CvInvoke.cvWatershed(image, marker);
CvInvoke.cvCmpS(marker, 0.10, mask, CMP_TYPE.CV_CMP_GT);
imageBox1.Image = mask;
Any Idea how to convert Image type to Image<Bgr, Byte> type?
I get the image from PictureBox Control and I need to convert it to Image<Bgr, Byte> type.
Image pictureBoxImage = pictureBox.Image;
Image<Bgr, Byte> image = // ...
According the documentation:
Creating image from Bitmap
It is also possible to create an Image<TColor, TDepth> from a .Net
Bitmap object
So, you should be able to do:
var image = new Image<Bgr, Byte>(new Bitmap(pictureBox.Image));
You can also do it like this:
Image<Bgr, Byte> IMG = new Image<Bgr, byte>((Bitmap)pictureBox1.Image);
OR
var IMG = new Image<Bgr, byte>((Bitmap)pictureBox1.Image);
For Emgu.CV 4.5 I had to add the Emgu.CV.Bitmap package and use bitmap.ToImage<Bgr, byte>():
using (Bitmap bitmap = new Bitmap(pictureBox.Image))
{
Image<Bgr, byte> image = bitmap.ToImage<Bgr, byte>();
}