当前位置: 首页 > article >正文

C#Halcon图像处理畸变校正之曲面校正

图像校正场景一般有两种,其一由镜头本身或安装角度引起,其二是被拍摄物品本身引起

1d86a5c7c2de42e2b280093157dd1b5c.png

理论处理流程

9c0c085580614f52975046f9ef1cd674.png

我的处理处理流程

1,加载网格校正图像

8fc4d4f40f7d46c39b7ce0b69c1ee5b3.png

2,确定符合条件的网格区域

624c4a1c77e440098d68eedd86950cbb.png

3,显示网格鞍点

f1159907c5d64d9dbd15ae05a652f018.png

4,显示网格线

421989c3f9284c7e8bed0554c7dccbe1.png

5,确定最终需要扭曲校正的图像

19a5daa30a214c58a6f0718fb6e66bc5.png

6,显示校正后图像

48b0da0eea4941f0a763ee81b61bd7a9.png

7,加载需要校正的图像

a483c1b3c99f488fb975e1bd180fa6ab.png

8,显示校正后图像效果

b1ebcab1cca0452fadddac09dcf309d1.png

显而易见,校正后的图像在字符识别,缺陷检测,尺寸测量等方面检测效果要优于原图。

附上源码

(注意,源码仅供流程参考,在实战项目过程中,方法最好封装成类亦或者Dll文件,参数可以适当开放方便后期调试,映射关系需保存本地,软件重启需重新读取参数)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ViewControl;
using HalconDotNet;
using System.Reflection.Emit;
using static System.Net.Mime.MediaTypeNames;
namespace DeepLearningTest1
{
    public partial class Form1 : Form
    {
        HalconView HW;

        HObject HIMage = new HObject(), ho_ImageReduced=new HObject(),ho_ConnectingLines=new HObject(), ho_Map=new HObject();
        HObject ho_ImageMapped =new HObject();
        HObject ho_GridRegion;
        HTuple  hv_Row = new HTuple(), hv_Col = new HTuple();


        public Form1()
        {
            InitializeComponent();
            HW = new HalconView();
            HW.HWindowControl.BackColor = Color.White;
            splitContainer1.Panel2.Controls.Add(HW);
            HW.Dock = DockStyle.Fill;
        }

       

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {

                OpenFileDialog openFileDialog = new OpenFileDialog();
                //openFileDialog.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory;
                openFileDialog.Filter = "图片文件(*.bmp;*.jpg;*.gif;*.png;*.tiff;*.tif)|*.bmp;*.jpg;*.gif;*.png;*.tiff;*.tif";
                openFileDialog.RestoreDirectory = true;
                openFileDialog.FilterIndex = 1;
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    label3.Text = openFileDialog.FileName;
                    HOperatorSet.ReadImage(out HIMage, label3.Text);
                    
                    HW.DispImage(HIMage, true);
                }
               
            }
            catch (Exception ex)
            {
                MessageBox.Show("加载图片失败  " + ex.ToString());
            }

        }
      
        /// <summary>
        /// 1 确定整流网格区域
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            if (!HIMage.IsInitialized()) { MessageBox.Show("图片为空"); return; }
            
            HOperatorSet.GenEmptyObj(out ho_GridRegion);            
            ho_GridRegion.Dispose();
            HOperatorSet.FindRectificationGrid(HIMage, out ho_GridRegion, 25,10);
            ho_ImageReduced.Dispose();
            HOperatorSet.ReduceDomain(HIMage, ho_GridRegion, out ho_ImageReduced);
            HW.DispObject(ho_GridRegion);
        }
        /// <summary>
        ///2 确定网格点。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            //---------------------2-----------------------------
            //确定网格点。
            HTuple hv_Threshold = new HTuple();
            HObject  ho_SaddlePoints;
            HOperatorSet.GenEmptyObj(out ho_SaddlePoints);
            hv_Row.Dispose(); hv_Col.Dispose();
            HOperatorSet.SaddlePointsSubPix(ho_ImageReduced, "facet", 1.5,
                5, out hv_Row, out hv_Col);
            ho_SaddlePoints.Dispose();
            HOperatorSet.GenCrossContourXld(out ho_SaddlePoints, hv_Row, hv_Col, 6, 0.785398);
            HOperatorSet.SetColor(HW.HalconWindow, "red");
            HW.DispObject(HIMage);
            HW.DispObject(ho_SaddlePoints);
        }
        /// <summary>
        /// 网格线区域
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button4_Click(object sender, EventArgs e)
        {
            HTuple hv_SigmaConnectGridPoints = new HTuple();
            HTuple hv_MaxDist = new HTuple();
            //------------------------3------------------------
            //确定网格线。
            ho_ConnectingLines.Dispose();
            HOperatorSet.ConnectGridPoints(ho_ImageReduced, out ho_ConnectingLines, hv_Row, hv_Col, 0.9, 5.0);
            HW.DispObject(HIMage);
            HW.DispObject(ho_ConnectingLines);
        }

        /// <summary>
        /// 输出映射关系
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button5_Click(object sender, EventArgs e)
        {

            HObject  ho_Meshes;
            HOperatorSet.GenEmptyObj(out ho_Meshes);
            HTuple hv_GridSpacing = new HTuple();
            ho_Map.Dispose(); ho_Meshes.Dispose();
            HOperatorSet.GenGridRectificationMap(ho_ImageReduced, 20, out ho_Map,
                out ho_Meshes, hv_GridSpacing, 0, hv_Row, hv_Col, "bilinear");
            HW.DispObject(HIMage);
            HW.DispObject(ho_Meshes);
        }

        /// <summary>
        /// 映射原图像
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button6_Click(object sender, EventArgs e)
        {

            ho_ImageMapped.Dispose();
            HOperatorSet.MapImage(ho_ImageReduced, ho_Map, out ho_ImageMapped);
            HW.DispObject(ho_ImageMapped);
        }
        /// <summary>
        /// 加载其他图像映射
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button7_Click(object sender, EventArgs e)
        {
            ho_ImageReduced.Dispose();
            HOperatorSet.ReduceDomain(HIMage, ho_GridRegion, out ho_ImageReduced);
            ho_ImageMapped.Dispose();
            HOperatorSet.MapImage(ho_ImageReduced, ho_Map, out ho_ImageMapped);
            HW.DispObject(ho_ImageMapped);

        }
    }
}

 

 

 


http://www.kler.cn/a/460872.html

相关文章:

  • 基于 GPUTasker 的 GPU 使用情况钉钉推送机器人实现
  • MySQL初始安装登录:ERROR 2003 (HY000): Can‘t connect to MySQL server on
  • C语言面的向对象编程(OOP)
  • 数字化供应链创新解决方案在零售行业的应用研究——以开源AI智能名片S2B2C商城小程序为例
  • 电视广播制式:N制与P制
  • Lua迭代器如何使用?
  • 短视频生活服务商是干什么的?本地生活服务系统源码部署是什么意思?靠谱吗?
  • MySQL Workbench安装教程以及菜单汉化
  • 查询docker overlay2文件夹下的 c7ffc13c49xxx是哪一个容器使用的
  • 1、CC2530、zigbee期末考试选择、填空题含答案
  • Python自学 - 引用与拷贝探索(防坑关键知识)
  • Spring-Mybatis 2.0
  • 【C语言】可移植性陷阱与缺陷(一):应对C语言标准变更
  • 单元测试3.0+ @RunWith(JMockit.class)+mock+Expectations
  • PyTorch快速入门教程【小土堆】之网络模型的保存和读取
  • MAC系统QT Creator的快捷键
  • 运维人员的Python详细学习路线
  • JVM之Class文件详解
  • 【前端】Node.js使用教程
  • 《Vue进阶教程》第三十一课:ref的初步实现
  • 2025元旦源码免费送
  • 探索数据之美,Plotly引领可视化新风尚
  • 代码随想录算法训练营DAY17
  • Rust日志库tklog0.2.9—支持混合时间文件大小备份模式
  • windows下VS release调试
  • Stm32小实验1