halcon+csharp多图像拼接实现-阿里云开发者社区

开发者社区> 禾路> 正文

halcon+csharp多图像拼接实现

简介: 简单的来说,就是将 一类的图片最后拼接成为这样的结果 这个图片有点大呀。 基本步骤: 1、halcon进行仿射变化进行镜头畸变。这个可以参考halcon中一个二维码畸变的例子; 2、基于模版匹配找出偏移值,然后进行拼接。
+关注继续查看

简单的来说,就是将

一类的图片最后拼接成为这样的结果

这个图片有点大呀。

基本步骤:

1、halcon进行仿射变化进行镜头畸变。这个可以参考halcon中一个二维码畸变的例子;

2、基于模版匹配找出偏移值,然后进行拼接。这个可以参考halcon中一个拼接的例子;

3、对交接处进行融合,这个是本文的关键。

首先,这个融合halcon中是没有方法的,所以要自己实现。首先要看论文《基于Halcon的图像拼接算法研究_谭杰》。然后文中有两种方法,因为本例没有产生旋转,所以采用第一种就可以。融合部分代码如下

for i:=RowStart to RowEnd by 1
    for j:=450 to 1560 by 1
        get_grayval(Imageresult1, i,100, Grayval1)
        get_grayval(Imageresult2, i, 100, Grayval2)
        grayval0 := (Grayval1 * yinzhi + Grayval2 * (100-yinzhi))/100
        set_grayval(Imageresult0, i, j, grayval0)
    endfor
    yinzhi := yinzhi -1
endfor

接下来就是效率问题,由于halcon是高级语言,为了提高效率,需要在csharp中直接操作内存,进行类似的操作。所以需要将这段代码改写成为csharp的形式。代码如下

using System;
using System.Collections.Generic;
using System.Text;
//新添加
using HalconDotNet;

//2013年10月24日14:54:09 所有图片融和的重构
namespace Halcon10test
{
    public  class  HalconHepler
    {
       
#region 停止HDevelopStop
        public void HDevelopStop()
        {
        }
#endregion
#region 显示继续信息 disp_continue_message    
        public void disp_continue_message(HTuple hv_WindowHandle, HTuple hv_Color, HTuple hv_Box)
        {

            HTuple hv_ContinueMessage, hv_Row, hv_Column;
            HTuple hv_Width, hv_Height, hv_Ascent, hv_Descent, hv_TextWidth;
            HTuple hv_TextHeight;
            hv_ContinueMessage = "按下(F5)程序将继续";
            HOperatorSet.GetWindowExtents(hv_WindowHandle, out hv_Row, out hv_Column, out hv_Width,
                out hv_Height);
            HOperatorSet.GetStringExtents(hv_WindowHandle, (" " + hv_ContinueMessage) + " ",
                out hv_Ascent, out hv_Descent, out hv_TextWidth, out hv_TextHeight);
            disp_message(hv_WindowHandle, hv_ContinueMessage, "window", (hv_Height - hv_TextHeight) - 12,
                (hv_Width - hv_TextWidth) - 12, hv_Color, hv_Box);

            return;
        }
#endregion
#region 显示信息
        public void disp_message(HTuple hv_WindowHandle, HTuple hv_String, HTuple hv_CoordSystem,
            HTuple hv_Row, HTuple hv_Column, HTuple hv_Color, HTuple hv_Box)
        {
            HTuple hv_Red, hv_Green, hv_Blue, hv_Row1Part;
            HTuple hv_Column1Part, hv_Row2Part, hv_Column2Part, hv_RowWin;
            HTuple hv_ColumnWin, hv_WidthWin, hv_HeightWin, hv_MaxAscent;
            HTuple hv_MaxDescent, hv_MaxWidth, hv_MaxHeight, hv_R1 = new HTuple();
            HTuple hv_C1 = new HTuple(), hv_FactorRow = new HTuple(), hv_FactorColumn = new HTuple();
            HTuple hv_Width = new HTuple(), hv_Index = new HTuple(), hv_Ascent = new HTuple();
            HTuple hv_Descent = new HTuple(), hv_W = new HTuple(), hv_H = new HTuple();
            HTuple hv_FrameHeight = new HTuple(), hv_FrameWidth = new HTuple();
            HTuple hv_R2 = new HTuple(), hv_C2 = new HTuple(), hv_DrawMode = new HTuple();
            HTuple hv_Exception = new HTuple(), hv_CurrentColor = new HTuple();

            HTuple hv_Color_COPY_INP_TMP = hv_Color.Clone();
            HTuple hv_Column_COPY_INP_TMP = hv_Column.Clone();
            HTuple hv_Row_COPY_INP_TMP = hv_Row.Clone();
            HTuple hv_String_COPY_INP_TMP = hv_String.Clone();

            HOperatorSet.GetRgb(hv_WindowHandle, out hv_Red, out hv_Green, out hv_Blue);
            HOperatorSet.GetPart(hv_WindowHandle, out hv_Row1Part, out hv_Column1Part, out hv_Row2Part,
                out hv_Column2Part);
            HOperatorSet.GetWindowExtents(hv_WindowHandle, out hv_RowWin, out hv_ColumnWin,
                out hv_WidthWin, out hv_HeightWin);
            HOperatorSet.SetPart(hv_WindowHandle, 0, 0, hv_HeightWin - 1, hv_WidthWin - 1);
            //
            //default settings
            if ((int)(new HTuple(hv_Row_COPY_INP_TMP.TupleEqual(-1))) != 0)
            {
                hv_Row_COPY_INP_TMP = 12;
            }
            if ((int)(new HTuple(hv_Column_COPY_INP_TMP.TupleEqual(-1))) != 0)
            {
                hv_Column_COPY_INP_TMP = 12;
            }
            if ((int)(new HTuple(hv_Color_COPY_INP_TMP.TupleEqual(new HTuple()))) != 0)
            {
                hv_Color_COPY_INP_TMP = "";
            }
            //
            hv_String_COPY_INP_TMP = ((("" + hv_String_COPY_INP_TMP) + "")).TupleSplit("\n");
            //
            //Estimate extentions of text depending on font size.
            HOperatorSet.GetFontExtents(hv_WindowHandle, out hv_MaxAscent, out hv_MaxDescent,
                out hv_MaxWidth, out hv_MaxHeight);
            if ((int)(new HTuple(hv_CoordSystem.TupleEqual("window"))) != 0)
            {
                hv_R1 = hv_Row_COPY_INP_TMP.Clone();
                hv_C1 = hv_Column_COPY_INP_TMP.Clone();
            }
            else
            {
                //transform image to window coordinates
                hv_FactorRow = (1.0 * hv_HeightWin) / ((hv_Row2Part - hv_Row1Part) + 1);
                hv_FactorColumn = (1.0 * hv_WidthWin) / ((hv_Column2Part - hv_Column1Part) + 1);
                hv_R1 = ((hv_Row_COPY_INP_TMP - hv_Row1Part) + 0.5) * hv_FactorRow;
                hv_C1 = ((hv_Column_COPY_INP_TMP - hv_Column1Part) + 0.5) * hv_FactorColumn;
            }
            //
            //display text box depending on text size
            if ((int)(new HTuple(hv_Box.TupleEqual("true"))) != 0)
            {
                //calculate box extents
                hv_String_COPY_INP_TMP = (" " + hv_String_COPY_INP_TMP) + " ";
                hv_Width = new HTuple();
                for (hv_Index = 0; (int)hv_Index <= (int)((new HTuple(hv_String_COPY_INP_TMP.TupleLength()
                    )) - 1); hv_Index = (int)hv_Index + 1)
                {
                    HOperatorSet.GetStringExtents(hv_WindowHandle, hv_String_COPY_INP_TMP.TupleSelect(
                        hv_Index), out hv_Ascent, out hv_Descent, out hv_W, out hv_H);
                    hv_Width = hv_Width.TupleConcat(hv_W);
                }
                hv_FrameHeight = hv_MaxHeight * (new HTuple(hv_String_COPY_INP_TMP.TupleLength()
                    ));
                hv_FrameWidth = (((new HTuple(0)).TupleConcat(hv_Width))).TupleMax();
                hv_R2 = hv_R1 + hv_FrameHeight;
                hv_C2 = hv_C1 + hv_FrameWidth;
                //display rectangles
                HOperatorSet.GetDraw(hv_WindowHandle, out hv_DrawMode);
                HOperatorSet.SetDraw(hv_WindowHandle, "fill");
                HOperatorSet.SetColor(hv_WindowHandle, "light gray");
                HOperatorSet.DispRectangle1(hv_WindowHandle, hv_R1 + 3, hv_C1 + 3, hv_R2 + 3, hv_C2 + 3);
                HOperatorSet.SetColor(hv_WindowHandle, "white");
                HOperatorSet.DispRectangle1(hv_WindowHandle, hv_R1, hv_C1, hv_R2, hv_C2);
                HOperatorSet.SetDraw(hv_WindowHandle, hv_DrawMode);
            }
            else if ((int)(new HTuple(hv_Box.TupleNotEqual("false"))) != 0)
            {
                hv_Exception = "Wrong value of control parameter Box";
                throw new HalconException(hv_Exception);
            }
            //Write text.
            for (hv_Index = 0; (int)hv_Index <= (int)((new HTuple(hv_String_COPY_INP_TMP.TupleLength()
                )) - 1); hv_Index = (int)hv_Index + 1)
            {
                hv_CurrentColor = hv_Color_COPY_INP_TMP.TupleSelect(hv_Index % (new HTuple(hv_Color_COPY_INP_TMP.TupleLength()
                    )));
                if ((int)((new HTuple(hv_CurrentColor.TupleNotEqual(""))).TupleAnd(new HTuple(hv_CurrentColor.TupleNotEqual(
                    "auto")))) != 0)
                {
                    HOperatorSet.SetColor(hv_WindowHandle, hv_CurrentColor);
                }
                else
                {
                    HOperatorSet.SetRgb(hv_WindowHandle, hv_Red, hv_Green, hv_Blue);
                }
                hv_Row_COPY_INP_TMP = hv_R1 + (hv_MaxHeight * hv_Index);
                HOperatorSet.SetTposition(hv_WindowHandle, hv_Row_COPY_INP_TMP, hv_C1);
                HOperatorSet.WriteString(hv_WindowHandle, hv_String_COPY_INP_TMP.TupleSelect(
                    hv_Index));
            }
            //reset changed window settings
            HOperatorSet.SetRgb(hv_WindowHandle, hv_Red, hv_Green, hv_Blue);
            HOperatorSet.SetPart(hv_WindowHandle, hv_Row1Part, hv_Column1Part, hv_Row2Part,
                hv_Column2Part);

            return;
        }
#endregion
#region 设置字体

        public void set_display_font(HTuple hv_WindowHandle, HTuple hv_Size, HTuple hv_Font,
            HTuple hv_Bold, HTuple hv_Slant)
        {
            HTuple hv_OS, hv_Exception = new HTuple();
            HTuple hv_AllowedFontSizes = new HTuple(), hv_Distances = new HTuple();
            HTuple hv_Indices = new HTuple();

            HTuple hv_Bold_COPY_INP_TMP = hv_Bold.Clone();
            HTuple hv_Font_COPY_INP_TMP = hv_Font.Clone();
            HTuple hv_Size_COPY_INP_TMP = hv_Size.Clone();
            HTuple hv_Slant_COPY_INP_TMP = hv_Slant.Clone();

            HOperatorSet.GetSystem("operating_system", out hv_OS);
            if ((int)((new HTuple(hv_Size_COPY_INP_TMP.TupleEqual(new HTuple()))).TupleOr(
                new HTuple(hv_Size_COPY_INP_TMP.TupleEqual(-1)))) != 0)
            {
                hv_Size_COPY_INP_TMP = 16;
            }
            if ((int)(new HTuple((((hv_OS.TupleStrFirstN(2)).TupleStrLastN(0))).TupleEqual(
                "Win"))) != 0)
            {
                //set font on Windows systems
                if ((int)((new HTuple((new HTuple(hv_Font_COPY_INP_TMP.TupleEqual("mono"))).TupleOr(
                    new HTuple(hv_Font_COPY_INP_TMP.TupleEqual("Courier"))))).TupleOr(new HTuple(hv_Font_COPY_INP_TMP.TupleEqual(
                    "courier")))) != 0)
                {
                    hv_Font_COPY_INP_TMP = "Courier New";
                }
                else if ((int)(new HTuple(hv_Font_COPY_INP_TMP.TupleEqual("sans"))) != 0)
                {
                    hv_Font_COPY_INP_TMP = "Arial";
                }
                else if ((int)(new HTuple(hv_Font_COPY_INP_TMP.TupleEqual("serif"))) != 0)
                {
                    hv_Font_COPY_INP_TMP = "Times New Roman";
                }
                if ((int)(new HTuple(hv_Bold_COPY_INP_TMP.TupleEqual("true"))) != 0)
                {
                    hv_Bold_COPY_INP_TMP = 1;
                }
                else if ((int)(new HTuple(hv_Bold_COPY_INP_TMP.TupleEqual("false"))) != 0)
                {
                    hv_Bold_COPY_INP_TMP = 0;
                }
                else
                {
                    hv_Exception = "Wrong value of control parameter Bold";
                    throw new HalconException(hv_Exception);
                }
                if ((int)(new HTuple(hv_Slant_COPY_INP_TMP.TupleEqual("true"))) != 0)
                {
                    hv_Slant_COPY_INP_TMP = 1;
                }
                else if ((int)(new HTuple(hv_Slant_COPY_INP_TMP.TupleEqual("false"))) != 0)
                {
                    hv_Slant_COPY_INP_TMP = 0;
                }
                else
                {
                    hv_Exception = "Wrong value of control parameter Slant";
                    throw new HalconException(hv_Exception);
                }
                try
                {
                    HOperatorSet.SetFont(hv_WindowHandle, ((((((("-" + hv_Font_COPY_INP_TMP) + "-") + hv_Size_COPY_INP_TMP) + "-*-") + hv_Slant_COPY_INP_TMP) + "-*-*-") + hv_Bold_COPY_INP_TMP) + "-");
                }
                // catch (Exception)
                catch (HalconException HDevExpDefaultException1)
                {
                    HDevExpDefaultException1.ToHTuple(out hv_Exception);
                    throw new HalconException(hv_Exception);
                }
            }
            else
            {
                //set font for UNIX systems
                hv_Size_COPY_INP_TMP = hv_Size_COPY_INP_TMP * 1.25;
                hv_AllowedFontSizes = new HTuple();
                hv_AllowedFontSizes[0] = 11;
                hv_AllowedFontSizes[1] = 14;
                hv_AllowedFontSizes[2] = 17;
                hv_AllowedFontSizes[3] = 20;
                hv_AllowedFontSizes[4] = 25;
                hv_AllowedFontSizes[5] = 34;
                if ((int)(new HTuple(((hv_AllowedFontSizes.TupleFind(hv_Size_COPY_INP_TMP))).TupleEqual(
                    -1))) != 0)
                {
                    hv_Distances = ((hv_AllowedFontSizes - hv_Size_COPY_INP_TMP)).TupleAbs();
                    HOperatorSet.TupleSortIndex(hv_Distances, out hv_Indices);
                    hv_Size_COPY_INP_TMP = hv_AllowedFontSizes.TupleSelect(hv_Indices.TupleSelect(
                        0));
                }
                if ((int)((new HTuple(hv_Font_COPY_INP_TMP.TupleEqual("mono"))).TupleOr(new HTuple(hv_Font_COPY_INP_TMP.TupleEqual(
                    "Courier")))) != 0)
                {
                    hv_Font_COPY_INP_TMP = "courier";
                }
                else if ((int)(new HTuple(hv_Font_COPY_INP_TMP.TupleEqual("sans"))) != 0)
                {
                    hv_Font_COPY_INP_TMP = "helvetica";
                }
                else if ((int)(new HTuple(hv_Font_COPY_INP_TMP.TupleEqual("serif"))) != 0)
                {
                    hv_Font_COPY_INP_TMP = "times";
                }
                if ((int)(new HTuple(hv_Bold_COPY_INP_TMP.TupleEqual("true"))) != 0)
                {
                    hv_Bold_COPY_INP_TMP = "bold";
                }
                else if ((int)(new HTuple(hv_Bold_COPY_INP_TMP.TupleEqual("false"))) != 0)
                {
                    hv_Bold_COPY_INP_TMP = "medium";
                }
                else
                {
                    hv_Exception = "Wrong value of control parameter Bold";
                    throw new HalconException(hv_Exception);
                }
                if ((int)(new HTuple(hv_Slant_COPY_INP_TMP.TupleEqual("true"))) != 0)
                {
                    if ((int)(new HTuple(hv_Font_COPY_INP_TMP.TupleEqual("times"))) != 0)
                    {
                        hv_Slant_COPY_INP_TMP = "i";
                    }
                    else
                    {
                        hv_Slant_COPY_INP_TMP = "o";
                    }
                }
                else if ((int)(new HTuple(hv_Slant_COPY_INP_TMP.TupleEqual("false"))) != 0)
                {
                    hv_Slant_COPY_INP_TMP = "r";
                }
                else
                {
                    hv_Exception = "Wrong value of control parameter Slant";
                    throw new HalconException(hv_Exception);
                }
                try
                {
                    HOperatorSet.SetFont(hv_WindowHandle, ((((((("-adobe-" + hv_Font_COPY_INP_TMP) + "-") + hv_Bold_COPY_INP_TMP) + "-") + hv_Slant_COPY_INP_TMP) + "-normal-*-") + hv_Size_COPY_INP_TMP) + "-*-*-*-*-*-*-*");
                }
                // catch (Exception)
                catch (HalconException HDevExpDefaultException1)
                {
                    HDevExpDefaultException1.ToHTuple(out hv_Exception);
                    throw new HalconException(hv_Exception);
                }
            }

            return;
        }

  
#endregion
#region 核心函数
        //核心过程
        public unsafe void action(object objectname)
        {  
            //参数处理
            string filename = (string)objectname;
            string[] str = filename.Split(',');
            string inputname = str[0];
            string outputname = str[1];

            if (string.Empty == inputname)
            {
                return;
            }
            if (string.Empty == outputname)
            {
                return;
            }
            //变量定义和初始化
            HObject[] OTemp = new HObject[20];
            long SP_O = 0;
            HObject ho_ImageTemplete, ho_Image1, ho_Image2, ho_ImageTmp;
            HObject ho_Image11, ho_Image22, ho_ModelRegion, ho__TmpRegion;
            HObject ho_TemplateImage, ho_ModelContours, ho_Images1;
            HObject ho_Images2, ho_Black, ho_Imageresult0, ho_Imageresult2;
            HObject ho_Imageresult1;
          
            HTuple hv_Pointer_tmp0, hv_Type_tmp0, hv_Width_tmp0, hv_Height_tmp0;
            HTuple hv_Pointer_tmp1, hv_Type_tmp1, hv_Width_tmp1, hv_Height_tmp1;
            HTuple hv_Pointer_tmp2, hv_Type_tmp2, hv_Width_tmp2, hv_Height_tmp2;
            HTuple hv_HomMat2D, hv_Pointer, hv_Type, hv_Width;
            HTuple hv_Height, hv_ImageFiles, hv_Index, hv_ModelId;
            HTuple hv_Row1, hv_Col1, hv_Angle1, hv_Score1, hv_Row2;
            HTuple hv_Col2, hv_Angle2, hv_Score2, hv_i, hv_H = new HTuple();
            HTuple hv_j = new HTuple(), hv_a = new HTuple(), hv_b = new HTuple();
            HTuple hv_Grayval1 = new HTuple(), hv_Grayval2 = new HTuple();
            HTuple hv_grayval = new HTuple();

            HOperatorSet.GenEmptyObj(out ho_ImageTemplete);
            HOperatorSet.GenEmptyObj(out ho_Image1);
            HOperatorSet.GenEmptyObj(out ho_Image2);
            HOperatorSet.GenEmptyObj(out ho_Image11);
            HOperatorSet.GenEmptyObj(out ho_Image22);
            HOperatorSet.GenEmptyObj(out ho_ImageTmp);
            HOperatorSet.GenEmptyObj(out ho_ModelRegion);
            HOperatorSet.GenEmptyObj(out ho__TmpRegion);
            HOperatorSet.GenEmptyObj(out ho_TemplateImage);
            HOperatorSet.GenEmptyObj(out ho_ModelContours);
            HOperatorSet.GenEmptyObj(out ho_Images1);
            HOperatorSet.GenEmptyObj(out ho_Images2);
            HOperatorSet.GenEmptyObj(out ho_Black);
            HOperatorSet.GenEmptyObj(out ho_Imageresult0);
            HOperatorSet.GenEmptyObj(out ho_Imageresult2);
            HOperatorSet.GenEmptyObj(out ho_Imageresult1);

            if (HDevWindowStack.IsOpen())
            {
                HOperatorSet.SetDraw(HDevWindowStack.GetActive(), "margin");
            }

            //图片序列读取
            HOperatorSet.ListFiles(inputname, ((new HTuple("files")).TupleConcat(
                "follow_links")).TupleConcat("recursive"), out hv_ImageFiles);
            HOperatorSet.TupleRegexpSelect(hv_ImageFiles, (new HTuple("\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima)$")).TupleConcat(
                "ignore_case"), out hv_ImageFiles);
            //if hv_imageFiles.length!=15  这个问题可以下一步考虑

            //校正矩阵计算(参数人工设定,也可以机器标定)
            ho_ImageTemplete.Dispose();
            HOperatorSet.ReadImage(out ho_ImageTemplete, hv_ImageFiles.TupleSelect(0));
            HOperatorSet.HomVectorToProjHomMat2d((((new HTuple(0)).TupleConcat(1080)).TupleConcat(
                1080)).TupleConcat(0), (((new HTuple(472)).TupleConcat(327)).TupleConcat(
                1705)).TupleConcat(1543), (((new HTuple(1)).TupleConcat(1)).TupleConcat(1)).TupleConcat(
                1), (((new HTuple(0)).TupleConcat(1080)).TupleConcat(1080)).TupleConcat(0),
                (((new HTuple(472)).TupleConcat(472)).TupleConcat(1546)).TupleConcat(1546),
                (((new HTuple(1)).TupleConcat(1)).TupleConcat(1)).TupleConcat(1), "normalized_dlt",
                out hv_HomMat2D);
            HOperatorSet.GetImagePointer1(ho_ImageTemplete, out hv_Pointer, out hv_Type,
                out hv_Width, out hv_Height);

            HOperatorSet.ReadImage(out ho_Image1, hv_ImageFiles.TupleSelect(1));
            ho_Image2.Dispose();
            HOperatorSet.ReadImage(out ho_Image2, hv_ImageFiles.TupleSelect(2));
            ho_Image11.Dispose();
            HOperatorSet.ProjectiveTransImage(ho_Image1, out ho_Image11, hv_HomMat2D, "bilinear",
                "false", "false");
            ho_Image22.Dispose();
            HOperatorSet.ProjectiveTransImage(ho_Image2, out ho_Image22, hv_HomMat2D, "bilinear",
                "false", "false");

            OTemp[SP_O] = ho_Image22.CopyObj(1, -1);
            SP_O++;
            ho_Image22.Dispose();
            HOperatorSet.CropPart(OTemp[SP_O - 1], out ho_Image22, 100, 0, hv_Width, hv_Height);
            OTemp[SP_O - 1].Dispose();
            SP_O = 0;

            OTemp[SP_O] = ho_Image11.CopyObj(1, -1);
            SP_O++;
            ho_Image11.Dispose();
            HOperatorSet.CropPart(OTemp[SP_O - 1], out ho_Image11, 100, 0, hv_Width, hv_Height);
            OTemp[SP_O - 1].Dispose();
            SP_O = 0;

            //通过模板匹配计算得到偏移值
            HOperatorSet.SetSystem("border_shape_models", "false");
            ho_ModelRegion.Dispose();
            HOperatorSet.GenRectangle1(out ho_ModelRegion, 421.374, 1309.12, 521.374, 1415.2);
            ho__TmpRegion.Dispose();
            HOperatorSet.GenRectangle1(out ho__TmpRegion, 902.23, 1041.53, 977.66, 1333.17);
            OTemp[SP_O] = ho_ModelRegion.CopyObj(1, -1);
            SP_O++;
            ho_ModelRegion.Dispose();
            HOperatorSet.Union2(OTemp[SP_O - 1], ho__TmpRegion, out ho_ModelRegion);
            OTemp[SP_O - 1].Dispose();
            SP_O = 0;

            ho_TemplateImage.Dispose();
            HOperatorSet.ReduceDomain(ho_Image11, ho__TmpRegion, out ho_TemplateImage);

            HOperatorSet.CreateShapeModel(ho_TemplateImage, 4, (new HTuple(0)).TupleRad()
                , (new HTuple(360)).TupleRad(), (new HTuple(0.7706)).TupleRad(), (new HTuple("point_reduction_high")).TupleConcat(
                "no_pregeneration"), "use_polarity", ((new HTuple(21)).TupleConcat(33)).TupleConcat(
                5), 16, out hv_ModelId);

            ho_ModelContours.Dispose();
            HOperatorSet.GetShapeModelContours(out ho_ModelContours, hv_ModelId, 1);

            HOperatorSet.FindShapeModel(ho_Image11, hv_ModelId, (new HTuple(0)).TupleRad()
                , (new HTuple(0)).TupleRad(), 0.5, 1, 0.5, "least_squares", 4, 0.75, out hv_Row1,
                out hv_Col1, out hv_Angle1, out hv_Score1);

            HOperatorSet.FindShapeModel(ho_Image22, hv_ModelId, (new HTuple(0)).TupleRad()
                , (new HTuple(0)).TupleRad(), 0.1, 1, 0.5, "least_squares", 4, 0.75, out hv_Row2,
                out hv_Col2, out hv_Angle2, out hv_Score2);
            HOperatorSet.ClearShapeModel(hv_ModelId);
          
            //拼接(注意这里序号为0的图片没有参与拼接),这里假定所有图片的相对偏移是一致的,这在流水线上非常常见。
            for (hv_Index = 1; hv_Index <14; hv_Index ++) //14
            {
             #region hv_Index = 1

                if (hv_Index == 1) //第一幅图的情况
                {
                    ho_Image1.Dispose();
                    HOperatorSet.ReadImage(out ho_Image1, hv_ImageFiles.TupleSelect(hv_Index));
                    ho_Image2.Dispose();
                    HOperatorSet.ReadImage(out ho_Image2, hv_ImageFiles.TupleSelect(hv_Index + 1));
                    ho_Image11.Dispose();
                    HOperatorSet.ProjectiveTransImage(ho_Image1, out ho_Image11, hv_HomMat2D, "bilinear",
                        "false", "false");
                    ho_Image22.Dispose();
                    HOperatorSet.ProjectiveTransImage(ho_Image2, out ho_Image22, hv_HomMat2D, "bilinear",
                        "false", "false");

                    ho_Images1.Dispose();
                    HOperatorSet.GenEmptyObj(out ho_Images1);
                    ho_Images2.Dispose();
                    HOperatorSet.GenEmptyObj(out ho_Images2);
                    ho_Black.Dispose();
                    HOperatorSet.GenImageConst(out ho_Black, "byte", hv_Width, hv_Height);
                    OTemp[SP_O] = ho_Images1.CopyObj(1, -1);
                    SP_O++;
                    ho_Images1.Dispose();
                    HOperatorSet.ConcatObj(OTemp[SP_O - 1], ho_Image11, out ho_Images1);
                    OTemp[SP_O - 1].Dispose();
                    SP_O = 0;
                    OTemp[SP_O] = ho_Images1.CopyObj(1, -1);
                    SP_O++;
                    ho_Images1.Dispose();
                    HOperatorSet.ConcatObj(OTemp[SP_O - 1], ho_Image22, out ho_Images1);
                    OTemp[SP_O - 1].Dispose();
                    SP_O = 0;
                    ho_Imageresult0.Dispose();
                    //hv_Height+hv_Row1-hv_Row2为拼接后图片的长度
                    HOperatorSet.TileImagesOffset(ho_Images1, out ho_Imageresult0, (new HTuple(0)).TupleConcat(
                        hv_Row1 - hv_Row2), (new HTuple(0)).TupleConcat(0), (new HTuple(-1)).TupleConcat(
                        -1), (new HTuple(-1)).TupleConcat(-1), (new HTuple(-1)).TupleConcat(-1),
                        (new HTuple(-1)).TupleConcat(-1), hv_Width, hv_Height+hv_Row1-hv_Row2);

                    ho_Imageresult1.Dispose();
                    HOperatorSet.TileImagesOffset(ho_Image11, out ho_Imageresult1, 0, 0, -1, -1,
                        -1, -1, hv_Width, hv_Height + hv_Row1 - hv_Row2);
                    ho_Imageresult2.Dispose();
                    HOperatorSet.TileImagesOffset(ho_Image22, out ho_Imageresult2, hv_Row1 - hv_Row2,
                        0, -1, -1, -1, -1, hv_Width, hv_Height + hv_Row1 - hv_Row2);

                    //交界处融和,关键代码
                    HOperatorSet.GetImagePointer1(ho_Imageresult0, out hv_Pointer_tmp0, out hv_Type_tmp0, out hv_Width_tmp0, out hv_Height_tmp0);
                    HOperatorSet.GetImagePointer1(ho_Imageresult1, out hv_Pointer_tmp1, out hv_Type_tmp1, out hv_Width_tmp1, out hv_Height_tmp1);
                    HOperatorSet.GetImagePointer1(ho_Imageresult2, out hv_Pointer_tmp2, out hv_Type_tmp2, out hv_Width_tmp2, out hv_Height_tmp2);

                    long lWidth0 = (long)hv_Width_tmp0;  //现图
                    long lHeight0 = (long)hv_Height_tmp0;
                    long lWidth1 = (long)hv_Width_tmp1; //原图
                    long lHeight1 = (long)hv_Height_tmp1;
                    //         string sType = hv_Type_tmp.ToString();
                    Byte* IPByte0 = (Byte*)hv_Pointer_tmp0.I;
                    Byte* IPByte1 = (Byte*)hv_Pointer_tmp1.I;
                    Byte* IPByte2 = (Byte*)hv_Pointer_tmp2.I;
                    /*    long lrow = 0; long lcol = 0;*/
                    int irow1 = (int)hv_Row1.D; //row1
                    int irow2 = (int)hv_Row2.D;
                    int irow12 = Math.Abs(irow1 - irow2);

                    //读取到内存中
                    Byte[] G1 = new Byte[hv_Height_tmp1 * hv_Width_tmp1];
                    Byte[] G2 = new Byte[hv_Height_tmp1 * hv_Width_tmp1];
                    double a = 0; double b = 0;
                    for (int i = 0; i < lHeight1; i++)
                    {
                        for (int j = 0; j < lWidth1; j++)
                        {
                            G1[i * lWidth1 + j] = *IPByte1;
                            G2[i * lWidth1 + j] = *IPByte2;
                            IPByte1++;
                            IPByte2++;
                        }
                    }

                    //像素融和循环
                    for (int lcol = 0; lcol < lWidth0; lcol++)
                    {
                        for (int lrow = irow12; lrow < irow1; lrow++)
                        {

                            a = 1.0 * (irow1 - lrow) / irow2;
                            b = 1.0 * (lrow - irow12) / irow2;
                            IPByte0[lrow * lWidth0 + lcol] = (Byte)(G1[lrow * lWidth0 + lcol] * a + G2[lrow * lWidth0 + lcol] * b);
                        }

                    }
                    //把结果保存下来
                    HOperatorSet.CopyImage(ho_Imageresult0, out ho_ImageTmp);

                  #endregion
                }
                else   //不是第一幅图的情况
                {
                    ho_Image1.Dispose();
                    ho_Image11.Dispose();
                    HOperatorSet.CopyImage(ho_ImageTmp, out ho_Image1);
                    HOperatorSet.CopyImage(ho_ImageTmp, out ho_Image11);
                    ho_Image2.Dispose();
                    HOperatorSet.ReadImage(out ho_Image2, hv_ImageFiles.TupleSelect(hv_Index + 1));
               

                    //第二副图片需要镜头畸变
                    ho_Image22.Dispose();
                    HOperatorSet.ProjectiveTransImage(ho_Image2, out ho_Image22, hv_HomMat2D, "bilinear",
                        "false", "false");

                    //注意,这里ho_Images1变成图片组了,这个代码风格有问题
                    ho_Images1.Dispose();
                    HOperatorSet.GenEmptyObj(out ho_Images1);
                    ho_Images2.Dispose();
                    HOperatorSet.GenEmptyObj(out ho_Images2);

                    OTemp[SP_O] = ho_Images1.CopyObj(1, -1);
                    SP_O++;
                    ho_Images1.Dispose();
                    HOperatorSet.ConcatObj(OTemp[SP_O - 1], ho_Image11, out ho_Images1);
                    OTemp[SP_O - 1].Dispose();
                    SP_O = 0;
                    OTemp[SP_O] = ho_Images1.CopyObj(1, -1);
                    SP_O++;
                    ho_Images1.Dispose();
                    HOperatorSet.ConcatObj(OTemp[SP_O - 1], ho_Image22, out ho_Images1);
                    OTemp[SP_O - 1].Dispose();
                    SP_O = 0;
                    ho_Imageresult0.Dispose();
                    //hv_Height +(hv_Row1-hv_Row2)*hv_Index 是拼接后图片的长度
                    //(hv_Row1-hv_Row2)*hv_Index 是偏移长度
                    HOperatorSet.TileImagesOffset(ho_Images1, out ho_Imageresult0, (new HTuple(0)).TupleConcat(
                       (hv_Row1 - hv_Row2) * hv_Index), (new HTuple(0)).TupleConcat(0), (new HTuple(-1)).TupleConcat(
                        -1), (new HTuple(-1)).TupleConcat(-1), (new HTuple(-1)).TupleConcat(-1),
                        (new HTuple(-1)).TupleConcat(-1), hv_Width, hv_Height +(hv_Row1-hv_Row2)*hv_Index);

                     ho_Imageresult1.Dispose();
                     HOperatorSet.TileImagesOffset(ho_Image11, out ho_Imageresult1, 0, 0, -1, -1,
                         -1, -1, hv_Width, hv_Height + (hv_Row1 - hv_Row2) * hv_Index);
                     ho_Imageresult2.Dispose();
                     HOperatorSet.TileImagesOffset(ho_Image22, out ho_Imageresult2, (hv_Row1 - hv_Row2) * hv_Index,
                         0, -1, -1, -1, -1, hv_Width, hv_Height + (hv_Row1 - hv_Row2) * hv_Index);

                    //交界处融和,关键代码
                    HOperatorSet.GetImagePointer1(ho_Imageresult0, out hv_Pointer_tmp0, out hv_Type_tmp0, out hv_Width_tmp0, out hv_Height_tmp0);
                    HOperatorSet.GetImagePointer1(ho_Imageresult1, out hv_Pointer_tmp1, out hv_Type_tmp1, out hv_Width_tmp1, out hv_Height_tmp1);
                    HOperatorSet.GetImagePointer1(ho_Imageresult2, out hv_Pointer_tmp2, out hv_Type_tmp2, out hv_Width_tmp2, out hv_Height_tmp2);

                    long lWidth0 = (long)hv_Width_tmp0;  //现图
                    long lHeight0 = (long)hv_Height_tmp0;
                    long lWidth1 = (long)hv_Width_tmp1; //原图
                    long lHeight1 = (long)hv_Height_tmp1;
                    long lWidth2 = (long)hv_Width_tmp2; //原图
                    long lHeight2 = (long)hv_Height_tmp2;
                    //         string sType = hv_Type_tmp.ToString();
                    Byte* IPByte0 = (Byte*)hv_Pointer_tmp0.I;
                    Byte* IPByte1 = (Byte*)hv_Pointer_tmp1.I;
                    Byte* IPByte2 = (Byte*)hv_Pointer_tmp2.I;
                    /*    long lrow = 0; long lcol = 0;*/
                    int irow1 = (int)hv_Row1.D ; //row1
                    int irow2 = (int)hv_Row2.D ;
                    int irow12 = Math.Abs(irow1 - irow2);

                    //读取到内存中
                    Byte[] G1 = new Byte[hv_Height_tmp1 * hv_Width_tmp1];
                    Byte[] G2 = new Byte[hv_Height_tmp2 * hv_Width_tmp2];
                    double a = 0; double b = 0;
                    for (int i = 0; i < lHeight1; i++)
                    {
                        for (int j = 0; j < lWidth1; j++)
                        {
                             G1[i * lWidth1 + j] = *IPByte1;
                          
                            IPByte1++;
                        }
                    }
                    for (int i = 0; i < lHeight2; i++)
                    {
                        for (int j = 0; j < lWidth2; j++)
                        {
                            G2[i * lWidth2 + j] = *IPByte2;
                            IPByte2++;

                        }
                    }
                   IPByte1 = (Byte*)hv_Pointer_tmp1.I;
                   IPByte2 = (Byte*)hv_Pointer_tmp2.I;
                    int ioffset = irow12 * (hv_Index-1);

                    //像素融和循环
                    for (int lcol = 0; lcol < lWidth0; lcol++)
                    {
                        for (int lrow = irow12; lrow < irow1; lrow++)
                        {

                            a = 1.0 * (irow1 - lrow) / irow2;
                            b = 1.0 * (lrow - irow12) / irow2;
                            IPByte0[(lrow + ioffset) * lWidth0 + lcol] = (Byte)(G1[(lrow + ioffset) * lWidth0 + lcol] * a + G2[(lrow + ioffset) * lWidth0 + lcol] * b);

                        }
                    }
                    //把结果保存下来
                    HOperatorSet.CopyImage(ho_Imageresult0, out ho_ImageTmp);
                }

             
            }

   //成功输出结果
                HOperatorSet.WriteImage(ho_Imageresult0, "bmp", 0, outputname + "/" + "融合结果.bmp");

            ho_ImageTemplete.Dispose();
            ho_Image1.Dispose();
            ho_Image2.Dispose();
            ho_Image11.Dispose();
            ho_Image22.Dispose();
            ho_ModelRegion.Dispose();
            ho__TmpRegion.Dispose();
            ho_TemplateImage.Dispose();
            ho_ModelContours.Dispose();
            ho_Images1.Dispose();
            ho_Images2.Dispose();
            ho_Black.Dispose();
            ho_Imageresult0.Dispose();
            ho_Imageresult2.Dispose();
            ho_Imageresult1.Dispose();
            return;

        }
#endregion

    }
}

结果运行界面

15张8秒。如果还有问题,请联系1755311380(QQ)

 

目前方向:图像拼接融合、图像识别 联系方式:jsxyhelu@foxmail.com

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
8497 0
使用NAT网关轻松为单台云服务器设置多个公网IP
在应用中,有时会遇到用户询问如何使单台云服务器具备多个公网IP的问题。 具体如何操作呢,有了NAT网关这个也不是难题。
26502 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,大概有三种登录方式:
2790 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
10320 0
使用OpenApi弹性释放和设置云服务器ECS释放
云服务器ECS的一个重要特性就是按需创建资源。您可以在业务高峰期按需弹性的自定义规则进行资源创建,在完成业务计算的时候释放资源。本篇将提供几个Tips帮助您更加容易和自动化的完成云服务器的释放和弹性设置。
11885 0
windows server 2008阿里云ECS服务器安全设置
最近我们Sinesafe安全公司在为客户使用阿里云ecs服务器做安全的过程中,发现服务器基础安全性都没有做。为了为站长们提供更加有效的安全基础解决方案,我们Sinesafe将对阿里云服务器win2008 系统进行基础安全部署实战过程! 比较重要的几部分 1.
8739 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,云吞铺子总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系统盘、创建快照、配置安全组等操作如何登录ECS云服务器控制台? 1、先登录到阿里云ECS服务器控制台 2、点击顶部的“控制台” 3、通过左侧栏,切换到“云服务器ECS”即可,如下图所示 通过ECS控制台的远程连接来登录到云服务器 阿里云ECS云服务器自带远程连接功能,使用该功能可以登录到云服务器,简单且方便,如下图:点击“远程连接”,第一次连接会自动生成6位数字密码,输入密码即可登录到云服务器上。
21653 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
3666 0
+关注
禾路
图像处理工程师,专注图像处理多年,长期奋斗在图像增强、识别一线。实战经验丰富,研究开发的连铸体拼接算法、人脸美化算法、红外线血管增强识别系统、中药识别系统、石材大板识别系统等均已投入使用。对opencv有着深入理解和解析,以jsxyhelu账号参与OpenCV项目。
270
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载