Difference between two images using emgu - c#

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.

Related

Reading 16bit matrox imaging library with emgu

I am trying to view in a pictureBox a tif raw file uncompressed. that was generated with
"matrox imaging library"
I am using emgu.cv
I am doing:
Image<Gray, ushort> My_Image = new Image<Gray, ushort>(imgN);
Image<Gray, byte> My_Image1 = new Image<Gray, byte>(imgN);
and slso:
Image<Gray, byte> My_Image3 = My_Image.Convert<Gray, byte>();
I keep seeing black image,
any solutions?
I have also tried more combination resulting in black ...
This worked for me:
IntPtr img = CvInvoke.cvLoadImage(imgN,Emgu.CV.CvEnum.LOAD_IMAGE_TYPE.CV_LOAD_IMAGE_UNCHANGED);
MIplImage iplImage = (MIplImage)Marshal.PtrToStructure(img, typeof(MIplImage));
Image<Gray, UInt16> res;
res = new Image<Gray, UInt16>(1024, 872, iplImage.widthStep, iplImage.imageData);
imageBox1.Image = res;
using imageBox1

what is the function to find otsu threshold in emgu cv?

I don't need the thresholded image. I want the threshold. I found this in OpenCV.
cv::threshold( orig_img, thres_img, 0, 255, CV_THRESH_BINARY+CV_THRESH_OTSU );
Is there an equivalent in EmguCv. Thanks in advance.
PS. I need to use this threshold for canny edge detector
You can refer this code for Auto Canny Edge detector!
Image<Gray, byte> Img_Source_Gray = Img_Org_Gray.Copy();
Image<Gray, byte> Img_Egde_Gray = Img_Source_Gray.CopyBlank();
Image<Gray, byte> Img_SourceSmoothed_Gray = Img_Source_Gray.CopyBlank();
Image<Gray, byte> Img_Otsu_Gray = Img_Org_Gray.CopyBlank();
Img_SourceSmoothed_Gray = Img_Source_Gray.SmoothGaussian(3);
double CannyAccThresh = CvInvoke.cvThreshold(Img_EgdeNR_Gray.Ptr, Img_Otsu_Gray.Ptr, 0, 255, Emgu.CV.CvEnum.THRESH.CV_THRESH_OTSU | Emgu.CV.CvEnum.THRESH.CV_THRESH_BINARY);
double CannyThresh = 0.1 * CannyAccThresh;
Img_Otsu_Gray.Dispose();
Img_Egde_Gray = Img_SourceSmoothed_Gray.Canny(CannyThresh, CannyAccThresh);
imageBox2.Image = Img_Egde_Gray;

separating image after watershed using emgu.cv

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;

how to convert capture a image from webcam in Image<Hsv, Byte> format ?

I am doing the following code . Is there a way to convert Image <bgr,Byte> to Image <hsv,Byte>?
Image<Hsv, Byte> imgOriginal;
Image<Hsv, Byte> imgRed;
imgOriginal = capWebCam.QueryFrame();
Use the Convert function:
Image<Bgr, Byte> imageA;
Image<Hsv, Byte> imageB;
imageB = imageA.Convert<Hsv, Byte>();

Value range for Image HSV for color extraction EMGUCV

In the following,
Image<Hsv, Byte> hsvimg = img.Convert<Hsv, Byte>();
Image<Gray, Byte>[] channels = hsvimg.Split();
Image<Gray, Byte> imghue = channels[0];
Image<Gray, Byte> imgsat = channels[1];
Image<Gray, Byte> imgval = channels[2];
Image<Gray, byte> huefilter = imghue.InRange(new Gray(?), new Gray(?));
Image<Gray, byte> satfilter = imghue.InRange(new Gray(?), new Gray(?));
Image<Gray, byte> valfilter = imgval.InRange(new Gray(?), new Gray(?));
What is the range value of different channel (h, s, v) for different color extraction? Is it 0-255 or 0-128. I want to detect Orange, Black and Sky blue object for an image.
Can you try something like this for orange
Image<Gray, byte> huefilter =
imghue.InRange(new Gray(Color.Orange.GetHue() - 10),
new Gray(Color.Orange.GetHue() + 10));
-10 and +10 is just a guess and could be broad. just play with it and see what works.
for satfilter you can use Color.Orange.GetSaturation()
and for the third one, I'm assuming you can use Color.Orange.GetBrightness()

Categories

Resources