I'm doing a project to process brain injuries using Image Processing. In order to improve its accuracy, I need to extract only the brain matter from the skull.
Using EmguCV I was able to identify the inner and outer contours (Blue and Dark blue). Is there anyway to extract these identified contours into another image?
Image<Gray, byte> grayImage = new Image<Gray, byte>(bitmap);
Image<Bgr, byte> color = new Image<Bgr, byte>(bitmap);
grayImage = grayImage.ThresholdBinary(new Gray(220), new Gray(255));
using (MemStorage storage = new MemStorage())
{
for (Contour<Point> contours = grayImage.FindContours(
Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_TREE, storage); contours != null; contours = contours.HNext)
{
Contour<Point> currentContour = contours.ApproxPoly(contours.Perimeter * 0.015, storage);
if (currentContour.BoundingRectangle.Width > 20)
{
CvInvoke.cvDrawContours(color, contours, new MCvScalar(100), new MCvScalar(255), -1, 2, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, new Point(0, 0));
}
}
}
EmguCV 2.2.2
Expected output:
Related
I am trying to find and display the contours after canny edge detection.
My code is working but I only see a black screen - and not the contours.
What is wrong?
If I remove the related part for finding contours, I succesfully see canny detected edges.
private void Device_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
video = (Bitmap)eventArgs.Frame.Clone();
Bitmap video2 = (Bitmap)eventArgs.Frame.Clone();
if (mode == 1)
{
Grayscale gray = new Grayscale(0.2125, 0.7154, 0.0721);
Bitmap video3 = gray.Apply(video2);
CannyEdgeDetector canny = new CannyEdgeDetector(0, 10);
canny.ApplyInPlace(video3);
//pic.Image = video3;
//Image<Gray, byte> imgOutput = video3.Convert<Gray, byte>().ThresholdBinary(new Gray(100), new Gray(255));
Mat hier = new Mat();
Emgu.CV.Util.VectorOfVectorOfPoint contours = new Emgu.CV.Util.VectorOfVectorOfPoint();
Image<Gray, byte> imgout = new Image<Gray, byte>(video.Width, video.Height, new Gray(0));
CvInvoke.FindContours(imgout, contours, hier, Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);
CvInvoke.DrawContours(imgout, contours, -1, new MCvScalar(255, 0, 0));
pic.Image = imgout.Bitmap;
}
else
pic.Image = video;
}
I need help in this part of code. I need to make my contours visible on black Background when Check Box is checked. But, when I set a tick in Check Box, my contours are disappear. Code and Screen shot below. [That's my screenshot][1]
private Image<Bgr, byte> Find(Image<Bgr, byte> image)
{
Image<Gray, byte> outputImage = image.Convert<Gray, byte>().ThresholdBinary(new Gray(100), new Gray(255)); //перевод изображения в серый цвет и уменьшение шума
VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
Mat hierarchy = new Mat();
CvInvoke.FindContours(outputImage, contours, hierarchy, Emgu.CV.CvEnum.RetrType.Tree, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);
if (checkBox1.Checked)
{
Image<Gray, byte> blackBackground = new Image<Gray, byte>(outputImage.Width, outputImage.Height, new Gray(0));
CvInvoke.DrawContours(blackBackground, contours, -1, new MCvScalar(255, 0, 0));
pictureBox2.Image = blackBackground.Bitmap;
}
else
{
CvInvoke.DrawContours(image, contours, -1, new MCvScalar(255, 0, 0));
pictureBox2.Image = image.Bitmap;
}
return image;
}
[1]: https://i.stack.imgur.com/BdtUb.png
Why don't you create a copy of the bitmap and assign to the picturebox like this?
pictureBox2.Image = blackBackground.ToBitmap();
or
pictureBox2.Image = image.ToBitmap();
INPUT IMAGE
Hi I am try to learn EmguCV 3.3 and I have a question about blob counting.As you see in INPUT IMAGE I have black uneven blobs.
I am try to do something like this.
OUTPUT IMAGE
I need to draw rectangle around blobs and count them.
I tryied some approches but non of it work.
I need Help();
You can use FindCountours() or SimpleBlobDetection() to achieve that, here is an example code uses the first one:
Image<Gray, Byte> grayImage = new Image<Gray,Byte>(mRGrc.jpg);
Image<Gray, Byte> canny = new Image<Gray, byte>(grayImage.Size);
int counter = 0;
using (MemStorage storage = new MemStorage())
for (Contour<Point> contours = grayImage.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_TREE, storage);contours != null; contours = contours.HNext)
{
contours.ApproxPoly(contours.Perimeter * 0.05, storage);
CvInvoke.cvDrawContours(canny, contours, new MCvScalar(255), new MCvScalar(255), -1, 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, new Point(0, 0));
counter++;
}
using (MemStorage store = new MemStorage())
for (Contour<Point> contours1= grayImage.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_TREE, store); contours1 != null; contours1 = contours1.HNext)
{
Rectangle r = CvInvoke.cvBoundingRect(contours1, 1);
canny.Draw(r, new Gray(255), 1);
}
Console.Writeline("Number of blobs: " + counter);
I got a kinect mount in the ceiling pointing down to a table (that is roughly 2 to 3 meters of the kinect) and my objective is using the kinect depth stream, locate the objects and get their position to late send to unity. So for that i am using c sharp and opencv (emgu wrapper), i first use canny to get the edges and then use BoundingRect to create a box around the object.
The result is the as follows:
Original:
As you can see the stationary objects are no problem but the box around the hands (the first was a flyer on it) is to big and sometimes is even worse. Is there any other way (using opencv ) of getting the positions of the objects?
The objective is then to send the position and dimension (of the object) to unity (trough tcp/ip), so preferably the shapes have to squares or rectangles to easy manipulation on unity.
The code I have so far is:
Image<Bgr, Byte> grayImage = new Image<Bgr, Byte>("C:\\Users\\Pedro\\Desktop\\imgRva\\KinectSnapshot-03-48-01.png");
Image<Gray, Byte> gray = grayImage.Convert<Gray, Byte>().PyrDown().PyrUp();
CvInvoke.cvShowImage("texto", gray);
CvInvoke.cvWaitKey(0);
Image<Gray, Byte> bin = gray.ThresholdBinary(new Gray(40), new Gray(255));
Image<Gray, Byte> cannyEdges = bin.Canny(300, 300);
CvInvoke.cvShowImage("texto", cannyEdges);
CvInvoke.cvWaitKey(0);
Image<Gray, Byte> canny = new Image<Gray, byte>(cannyEdges.Size);
using (MemStorage storage = new MemStorage())
for (Contour<Point> contours = cannyEdges.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_TREE, storage); contours != null; contours = contours.HNext)
{
CvInvoke.cvDrawContours(canny, contours, new MCvScalar(255), new MCvScalar(255), -1, 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, new Point(0, 0));
}
using (MemStorage store = new MemStorage())
for (Contour<Point> contours1 = cannyEdges.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_TREE, store); contours1 != null; contours1 = contours1.HNext)
{
Rectangle r = CvInvoke.cvBoundingRect(contours1, 1);
canny.Draw(r, new Gray(255), 1);
Debug.WriteLine(r.Location + " x " + r.Width + " y " + r.Height);
}
CvInvoke.cvShowImage("texto", canny);
CvInvoke.cvWaitKey(0);
Ty
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");