Halcon フォトメトリック ステレオ テクノロジー

 産業分野において、表面検査は非常に幅広い応用分野です。Halcon の強化されたフォトメトリック ステレオ ビジョン手法を使用することで、3D 表面検出が強化されます。影を使用すると、物体の表面の隙間やへこみを簡単かつ迅速に検出できます。表面欠陥は、測光立体視法を使用して複雑な画像から簡単に見つけることができます。

1 測光ステレオ

    典型的なアプリケーション:

    測光ステレオの一般的な用途は、欠陥を表す表面の小さな不一致を検出したり、非平面文字の印刷検査などに使用される画像から光の方向の影響を除外したりすることです。フォトメトリック ステレオは絶対高さの再構成には適していないことに注意してください。つまり、焦点深度やライト シートなどの一般的な 3D 再構成アルゴリズムを置き換えることはできません。

    制限:

    hanlcon のフォトメトリック ステレオは Woodham のアルゴリズムに基づいているため、一方ではカメラが正投影を実行することを前提としています。つまり、テレセントリックレンズや焦点距離の長いレンズを使用する必要があります。一方、各光源が平行で均一なビームを提供すると仮定します。つまり、均一な強度のテレセントリック光源、あるいは離れた点光源を使用する必要があります。さらに、オブジェクトはランバート反射特性を持たなければなりません。つまり、入射光を拡散反射する必要があります。鏡面特性 (すなわち、鏡面または光沢) を持つオブジェクトまたはオブジェクトの領域は正しく処理されず、誤った結果が生じます。

    コレクション:

    テレセントリック レンズを備えたカメラは正投影的に、つまり再構成するシーンに対して垂直に配置する必要があります。画像のキャプチャ中、シーンに対するカメラの向きが変わってはなりません。対照的に、少なくとも 3 つのグレー値画像の場合、カメラに対する照明の方向を変更する必要があります。

    照明方向:

    画像ごとに、照明の方向をパラメータ内の角度 Slants と Tilts として指定する必要があります。これは、シーンに対する照明の方向を表します。

    傾きは、次のように、カメラの光軸と照明の方向の間の角度です。

    傾きは、物体面またはそれに平行な任意の面 (像面など) で測定されます。特に、画像の中心から右を指す方向と、平面に投影される光の方向との間の角度を表します。つまり、画像 (または対応するシーン) を見るとき、傾斜角 0 は光が右から来ていることを意味し、傾斜角 90 は光が上から来ていることを意味し、傾斜角 180 は光が下から来ていることを意味します。左、など。次のように:

    フォトメトリックステレオには、異なる照明方向を持つ少なくとも 3 つの画像が必要です。照明方向が多すぎると処理時間の増加につながります。できれば 4 ~ 6 方向です。傾斜角は 30°~60°の間で、傾斜角はオブジェクトの周りに均等に分散されます。実際には、アプリケーションでは、光源は次のように設定できます。

    使用される演算子:


//使用光度立体法重建表面
void PhotometricStereo(const HObject& Images, //输入图像
  HObject* HeightField,               //重建的高度字段
  HObject* Gradient,                  //曲面的梯度场
  HObject* Albedo,                    //表面的反照率
  const HTuple& Slants,               //相机与照明方向之间的角度
  const HTuple& Tilts,                //对象平面内照明方向的角度
  const HTuple& ResultType,           //请求结果的类型
  const HTuple& ReconstructionMethod, //重建方法
  const HTuple& GenParamName,         //一般参数名称
  const HTuple& GenParamValue)        //一般参数设置
//梯度场转平均曲率场
void DerivateVectorField(
  const HObject& VectorField,  //梯度场图像
  HObject* Result,             //返回平均曲率场图像
  const HTuple& Sigma,         //高斯系数
  const HTuple& Component)     //组件计算

2 認識された文字

    一部の銀行カードの裏面の番号については、従来のブロブ解析や周波数領域手法を使用すると目的を達成することが困難ですが、フォトメトリックステレオを使用することで前景と背景を分離することは比較的容易です。

    テストコード:


dev_update_off ()
ImageFiles := []
ImageFiles[0] := './1.png'
ImageFiles[1] := './2.png'
ImageFiles[2] := './3.png'
ImageFiles[3] := './4.png'
gen_empty_obj (Images)
for Index := 0 to |ImageFiles| - 1 by 1
       read_image (Image, ImageFiles[Index])      
       concat_obj (Images, Image, Images)  
       wait_seconds (0.3)
       *dev_display (Image)
endfor
Slants:=[45,45,45,45]
Tilts:=[0,90,180,270]
* 光度立体法
photometric_stereo (Images, HeightField, Gradient, Albedo, Slants, Tilts, 'all', 'poisson', [], [])
* 梯度场转平均曲率场
derivate_vector_field (Gradient, Result, 1, 'mean_curvature')
* 镜像
mirror_image (Result, Image, 'row')
mirror_image (Image, ImageMirror, 'column')
* 将灰度值分布在0到255之间
scale_image_max (ImageMirror, ImageScaleMax)
* 尝试在频域中继续处理
fft_generic (ImageScaleMax, ImageFFT, 'to_freq', -1, 'sqrt', 'dc_center', 'complex')
* 得到背景
get_image_size (ImageFFT, Width, Height)
gen_gauss_filter (ImageGauss, 10, 10, 0, 'none', 'dc_center', Width, Height)
gen_lowpass (ImageLowpass, 0.05, 'none', 'dc_center', Width, Height)
convol_fft (ImageFFT, ImageGauss, ImageConvol)
fft_generic (ImageConvol, ImageBackground, 'from_freq', 1, 'sqrt', 'dc_center', 'byte')
* 差分,去掉背景
sub_image (ImageScaleMax, ImageBackground, ImageSub, 1, 128)
median_image (ImageSub, ImageMedian, 'circle', 3, 'mirrored')

***字符识别
gen_rectangle1 (ROI_0, 629.385, 382.235, 852.788, 1515)
reduce_domain (ImageMedian, ROI_0, ImageReduced)
threshold (ImageReduced, Regions, 132, 205)

closing_circle (Regions, RegionClosing, 1.5)
connection (RegionClosing, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, ['area','width'], 'and', [850.44,14.96], [2000.01,53.38])
sort_region (SelectedRegions, SortedRegions, 'character', 'true', 'row')

reduce_domain (ImageReduced, SelectedRegions, ImageReduced1)

paint_region (ImageReduced, ImageReduced, WihteBackground, 255, 'fill')
paint_region (SortedRegions, WihteBackground, ImageResult, 0, 'fill')

read_ocr_class_mlp ('Industrial_0-9_NoRej.omc', OCRHandle)
do_ocr_multi_class_mlp (SortedRegions, ImageResult, OCRHandle, Class, Confidence)

dev_display (ImageResult)
dev_get_window (WindowHandle)
set_display_font (WindowHandle, 26, 'mono', 'true', 'false')
disp_message (WindowHandle, '由光度立体法求得:', 'image', 12, 12, 'black', 'true')
disp_message (WindowHandle, '卡号:'+sum(Class), 'image', 162, 12, 'black', 'true')
dev_update_on ()

結果は次のとおりです。

3 欠陥検出

    一部の表面欠陥検出は測光ステレオ法で解決できます

    テストコード:


*用于检查药物泡罩背面。
*输入4张从药泡背面拍摄的图像
dev_close_window ()
dev_update_off ()
*创建窗口
dev_open_window (0, 0, 512, 512, 'black', WindowHandle)
*设置字体
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')

* 读取不同角度拍摄的图像
read_image (Images, 'photometric_stereo/blister_back_0' + [1:4])
for I := 1 to 4 by 1
    Message := 'Acquire image ' + I + ' of 4'
    select_obj (Images, ObjectSelected, I)
    dev_display (ObjectSelected)
    disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
    wait_seconds (0.5)
endfor

* 
*应用光度立体仪测定反照率和表面梯度。
*Tilts参数是俯视图看光源的角度
Tilts := [6.1,95.0,-176.1,-86.8]
*Slants参数是主视图看光源的角度
Slants := [41.4,42.6,41.7,40.9]
*请求结果的类型。“梯度”,“反照率”
ResultType := ['gradient','albedo']

*核心算子
photometric_stereo (Images, HeightField, Gradient, Albedo, Slants, Tilts, ResultType, 'poisson', [], [])
* 
*显示反照率图像
dev_display (Albedo)
disp_message (WindowHandle, 'Albedo image', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 
*显示这张图片之后,有很多种方式去检测这张图片

* 计算曲面的高斯曲率
*使用梯度场作为操作符的输入
* derivate_vector_field。
*缺陷通常很容易在曲率图像中检测出来。
derivate_vector_field (Gradient, GaussCurvature, 1, 'gauss_curvature')
*使用区域分割的图像。
regiongrowing (GaussCurvature, Regions, 1, 1, 0.001, 250)
*选择宽度和高度都在150-200之间的图像
select_shape (Regions, TabletRegions, ['width','height'], 'and', [150,150], [200,200])
*形成一个凸形区域
shape_trans (TabletRegions, TabletRegions, 'convex')
*区域进行联合
union1 (TabletRegions, TabletRegions)
*以3.5的圆形进行腐蚀区域(减小region)
erosion_circle (TabletRegions, TabletRegions, 3.5)
*减少图像区域
reduce_domain (GaussCurvature, TabletRegions, ImageReduced)
*计算图像的绝对值(模数)。
abs_image (ImageReduced, ImageAbs)
*阈值分割
threshold (ImageAbs, Region, 0.03, 255)
*圆的闭运算
closing_circle (Region, RegionClosing, 10.5)
*将检测区域进行分离
connection (RegionClosing, ConnectedRegions)
*选择其中像素大小在10-99999之间的区域,就是error区域
select_shape (ConnectedRegions, Defects, 'area', 'and', 10, 99999)
*找到该区域的中心
area_center (Defects, Area, Row, Column)
*以中心为圆的中心,画一个半径
gen_circle (Circle, Row, Column, gen_tuple_const(|Row|,20.5))

dev_set_draw ('margin')
dev_set_color ('red')
dev_set_line_width (2)
dev_display (GaussCurvature)
dev_display (Circle)
Message := 'The defect can easily be detected'
Message[1] := 'in the surface curvature image'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
stop ()
* Display the defects in the albedo image
dev_set_draw ('margin')
dev_set_color ('red')
dev_display (Albedo)
dev_display (Circle)
disp_message (WindowHandle, 'Defect in albedo image', 'window', 12, 12, 'black', 'true')

    結果は次のとおりです。

おすすめ

転載: blog.csdn.net/qq_40732350/article/details/128346337