将轮廓与EMGU CV对齐

时间:2018-04-18 07:39:40

标签: c# opencv emgucv image-resizing dicom

工作:

现在我正在使用图像混合工具。它的作用是通过改变它们的不透明度来混合两个图像

我的问题:

这是第一张X射线图像。

Xray Image

这是第二张图像,它是光学图像。

Optical Image

当我混合这两个图像时,我将其作为输出。

Blended image

正如您在此处所见,与X射线图像相比,我的光学图像更小。我希望我的光学图像与X射线图像完美对齐。

我使用过的代码:

private BitmapSource processImage (BitmapSource bitm, bool gray)
    {
        int adaptiveThresholdBlockSize = 4;
        double adaptiveThresholdParameter = 1.2d;
        int cannyThreshold = 50;

        double maxArea_optic;
        double maxArea_gray;

        System.Drawing.Rectangle rect = new System.Drawing.Rectangle();

        Image<Gray, byte> source;
        Image<Gray, byte> optical;

        MemoryStream outStream = new MemoryStream();
        BitmapEncoder enc = new BmpBitmapEncoder();
        enc.Frames.Add(BitmapFrame.Create(bitm));
        enc.Save(outStream);
        var myBmp = new System.Drawing.Bitmap(outStream);

        Image<Bgr, byte> sampleImg = new Image<Bgr, byte>(myBmp);
        Image<Gray, byte> grayImg = sampleImg.Convert<Gray, byte>();
        grayImg = sampleImg.Convert<Gray, byte>().PyrDown().PyrUp();

        if (gray)
            source = grayImg;
        else
            optical = grayImg;

        grayImg = grayImg.SmoothBlur(10, 10, true);
        grayImg = grayImg.SmoothMedian(15);
        grayImg = grayImg.SmoothBilatral(7, 255, 34);
        grayImg = grayImg.SmoothGaussian(3, 3, 34.3, 45.3);

        grayImg._ThresholdBinary(new Gray(100), new Gray(255));

        Image<Gray, byte> cannyFrame = grayImg.Canny(new Gray(cannyThreshold), new Gray(cannyThreshold));

        CvInvoke.cvAdaptiveThreshold(grayImg, grayImg, 255, Emgu.CV.CvEnum.ADAPTIVE_THRESHOLD_TYPE.CV_ADAPTIVE_THRESH_MEAN_C, Emgu.CV.CvEnum.THRESH.CV_THRESH_BINARY, adaptiveThresholdBlockSize + adaptiveThresholdBlockSize % 2 + 1, adaptiveThresholdParameter);

        grayImg._Not(); //used for inverting the image

        if (cannyFrame != null)
            grayImg._Or(cannyFrame);

        //grayImg._ThresholdBinary(new Gray(100), new Gray(255));
        Contour<System.Drawing.Point> cont = grayImg.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST);

        double[] Area = new double[1000];
        double[] width = new double[1000];
        double[] height = new double[1000];
        int i = 0;

        for (Contour<System.Drawing.Point> contour = cont; contour != null; contour = contour.HNext)
        {
            System.Drawing.Point[] pts = contour.ToArray();
            //Area = new double[pts.Count()];
            //if(contour.Area > 1000)
            {
                Area[i] = (int)contour.Area;
                rect = CvInvoke.cvBoundingRect(contour, 1);
                //rect = contour.GetMinAreaRect().MinAreaRect();
                width[i] = rect.Width;
                height[i] = rect.Height;
                grayImg.Draw(rect, new Gray(150), 3);
            }
            i++;
        }

        if (gray)
        {
            maxArea_gray = Area.Max();
            int maxAreaIndex_gray = Area.ToList().IndexOf(maxArea_gray);
            rect_width_gray =  width[maxAreaIndex_gray];
            rect_height_gray = height[maxAreaIndex_gray];
        }
        else
        {
            maxArea_optic = Area.Max();
            int maxAreaIndex_optic = Area.ToList().IndexOf(maxArea_optic);
            rect_width_opt = width[maxAreaIndex_optic];
            rect_height_opt = height[maxAreaIndex_optic];

            grayImg.Resize((int)rect_width_gray, (int)rect_height_gray, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR);
        }

        System.Drawing.Bitmap frm = sampleImg.Bitmap;
        BitmapSource btm = Convert_toBitSource(frm);
        return btm;
    }

所以我在这里使用 EMGUCV 来获取两个图像的轮廓点。所以我突然停留在光学图像的大小调整部分,因为它包括调整图像大小和定位,最后对齐图像,使其看起来像这样。

所需输出

Required output

您能否建议我一些代码片段,以便从收集的轮廓点自动匹配轮廓。或者请给我一些有用的搜索链接。

提前致谢。

0 个答案:

没有答案