关于粽子的生产产线提速

本文探讨了如何利用智能视觉和机器人技术提升粽子生产线上包装环节的自动化水平。通过前端视觉拍照获取粽子大小和位置信息,机器人根据数据精确抓取并放入包装盒。文章介绍了手眼标定过程,并展示了使用Halcon进行模型识别定位的示例代码,旨在提高生产效率,尽管全面自动化可能因成本问题而不切实际。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我正在参加「初夏创意投稿大赛」详情请看:初夏创意投稿大赛

今天公司组织发福利,端午的福利,粽子、、、 也不是直接的发粽子。而是给你礼品卷,自己选择相应的礼品进行兑换。

fd94494f22f999b2222a23fc6aab3e8.jpg

931a278bdecf7d6c57723e460837438.jpg

就是这么个东西,由于我们公司一直致力于做工业智能化,我就查了一下粽子的生产流程: 我的个乖乖,从来没有关注过粽子的生产,今天以卡,基本上属于人工生产的方式,这怎么能忍。一个做智能制造的,怎么能忍受人工生产呢。所以,我就农了这篇文章,表达一下我的看法,当然了,实现全自动的可能性应该没有,应为预算太高,粽子一年就买几天,回本太慢了。

image.png

image.png 基本上都属于人工,那么我们就来对粽子生产的的某些功能进行升级吧!

粽子的分类以及抓取放到包装盒

由于我这里没有粽子的产线,智能放一个大体上相同的

image.png 我们通过前端的视觉拍照,得到粽子的大小以及在传送带上的位置,把他发送给机器人,机器人根据得到的数据在后方将粽子抓取到相应的包装盒。

前期标定

我们通过手眼标定的方式将机器人和相机标定到同一个坐标系下面,具体操作不走如下:

image.png

1.我们首先在视觉相机下方找到九个点,平且求出9个点在相机坐标下的像素坐标值P(i);

image.png 2.传送带万千移动,我们记录一下传送带往前走了的编码的脉冲量M;

3.将九个点的位置以机器人为坐标,记录下9个点的机器人坐标数据q(i);

image.png

我们通过机器人端的开发包建立随动坐标,将我们的数据传入到随动坐标中;

视觉这块,我们将的到的机械的坐标和视觉的坐标合二为一,通过halcon9点标定的方式来进行一个标定;

```js

*图像坐标 areacenter(SortedRegions,Area,Row,Column) % Columnrobot := [275,225,170,280,230,180,295,240,190]

*机器人9点的列坐标 Rowrobot := [55,50,45,5,0,-5,-50,-50,-50] *机器人9点的行坐标 vectortohommat2d(Row,Column,Rowrobot,Columnrobot,HomMat2D) *求解变换矩阵,HomMat2D是图像坐标和机械手坐标之间的关系 ```

`affinetranspoint_2d(HomMat2D,Row2,Column2,Qx,Qy)'

'*由像素坐标和标定方式求出机器人基础坐标系中的坐标 `

视觉程序

我们首先以粽子的原图作为模型,通过模型识别定位

示例如下:

image.png ```js


  • This example program uses shape-based matching to align ROIs for the measure
  • tool, which then inspects individual razor blades.
  • The program can be run in two modes: (1) with the full affine transformation
  • (2) using translate_measure
  • Modify the next line to switch between the modes. USINGTRANSLATEMEASURE := 0

  • general configuration of HDevelop devupdatewindow ('off')
  • image acquisition and window size readimage (ModelImage, 'razors1') getimagepointer1 (ModelImage, Pointer, Type, Width, Height) devclosewindow () devopenwindow (0, 0, Width, Height, 'white', WindowHandle) devsetpart (0, 0, Height - 1, Width - 1) devdisplay (ModelImage)
  • colors and other settings for the visualization devsetcolor ('cyan') devsetdraw ('margin') devsetline_width (2) stop ()
  • ------------------- start of the application ----------------
  • -> select the model object Row1 := 46 Column1 := 57 Row2 := 79 Column2 := 94 genrectangle1 (ROIPart1, Row1, Column1, Row2, Column2) genrectangle1 (ROIPart2, Row1 + 364, Column1 + 13, Row2 + 364, Column2 + 13) union2 (ROIPart1, ROIPart2, ModelROI) areacenter (ModelROI, Area, CenterROIRow, CenterROIColumn) devdisplay (ModelImage) dev_display (ModelROI) stop ()
  • -> create the model reducedomain (ModelImage, ModelROI, ImageROI) createshapemodel (ImageROI, 4, 0, 0, 'auto', 'none', 'usepolarity', 30, 10, ModelID) inspectshapemodel (ImageROI, ShapeModelImage, ShapeModelRegion, 1, 30) getshapemodelcontours (ShapeModel, ModelID, 1) devclearwindow () devsetcolor ('blue') devdisplay (ShapeModelRegion) stop ()
  • step 1: create variables describing the measurement ROIs and display them Rect1Row := 244 Rect1Col := 73 DistColRect1Rect2 := 17 Rect2Row := Rect1Row Rect2Col := Rect1Col + DistColRect1Rect2 RectPhi := rad(90) RectLength1 := 122 RectLength2 := 2 genrectangle2 (MeasureROI1, Rect1Row, Rect1Col, RectPhi, RectLength1, RectLength2) genrectangle2 (MeasureROI2, Rect2Row, Rect2Col, RectPhi, RectLength1, RectLength2) devdisplay (ModelImage) devsetcolor ('yellow') devdisplay (MeasureROI1) dev_display (MeasureROI2)
  • translate measurement ROIs to lie on XLD model (without clipping!) getsystem ('clipregion', OriginalClipRegion) setsystem ('clipregion', 'false') moveregion (MeasureROI1, MeasureROI1Ref, -CenterROIRow, -CenterROIColumn) moveregion (MeasureROI2, MeasureROI2Ref, -CenterROIRow, -CenterROIColumn) setsystem ('clipregion', OriginalClipRegion) DistRect1CenterRow := Rect1Row - CenterROIRow DistRect1CenterCol := Rect1Col - CenterROIColumn DistRect2CenterRow := Rect2Row - CenterROIRow DistRect2CenterCol := Rect2Col - CenterROIColumn if (USINGTRANSLATEMEASURE != 0)
    • -> measure objects are created only once in advance and then translated later genmeasurerectangle2 (Rect1Row, Rect1Col, RectPhi, RectLength1, RectLength2, Width, Height, 'bilinear', MeasureHandle1) genmeasurerectangle2 (Rect2Row, Rect2Col, RectPhi, RectLength1, RectLength2, Width, Height, 'bilinear', MeasureHandle2) endif stop ()
  • step 2: find the objects in another image readimage (SearchImage, 'razors2') devdisplay (SearchImage) findshapemodel (SearchImage, ModelID, 0, 0, 0.8, 0, 0.5, 'leastsquares', 0, 0.7, RowCheck, ColumnCheck, AngleCheck, Score) if (|Score| > 0) for i := 0 to |Score| - 1 by 1 * step 3: determine the affine transformation vectorangletorigid (0, 0, 0, RowCheck[i], ColumnCheck[i], AngleCheck[i], MovementOfObject) affinetranscontourxld (ShapeModel, ModelAtNewPosition, MovementOfObject) devdisplay (ModelAtNewPosition) * step 4: measure width and distance of the teeth * -> display the moved ROIs affinetransregion (MeasureROI1Ref, MeasureROI1AtNewPosition, MovementOfObject, 'constant') affinetransregion (MeasureROI2Ref, MeasureROI2AtNewPosition, MovementOfObject, 'constant') devdisplay (MeasureROI1AtNewPosition) devdisplay (MeasureROI2AtNewPosition) affinetranspixel (MovementOfObject, DistRect1CenterRow, DistRect1CenterCol, Rect1RowCheck, Rect1ColCheck) affinetranspixel (MovementOfObject, DistRect2CenterRow, DistRect2CenterCol, Rect2RowCheck, Rect2ColCheck) if (USINGTRANSLATEMEASURE != 0) * -> translate the already created measure objects translatemeasure (MeasureHandle1, Rect1RowCheck, Rect1ColCheck) translatemeasure (MeasureHandle2, Rect2RowCheck, Rect2ColCheck) measurepairs (SearchImage, MeasureHandle1, 2, 25, 'negative', 'all', RowEdge11, ColEdge11, Amp11, RowEdge21, ColEdge21, Amp21, Width1, Distance1) measurepairs (SearchImage, MeasureHandle2, 2, 25, 'negative', 'all', RowEdge12, ColEdge12, Amp12, RowEdge22, ColEdge22, Amp22, Width2, Distance2) else * -> create new measure objects and destroy them after the measurement RectPhiCheck := RectPhi + AngleCheck[i] genmeasurerectangle2 (Rect1RowCheck, Rect1ColCheck, RectPhiCheck, RectLength1, RectLength2, Width, Height, 'bilinear', MeasureHandle1) genmeasurerectangle2 (Rect2RowCheck, Rect2ColCheck, RectPhiCheck, RectLength1, RectLength2, Width, Height, 'bilinear', MeasureHandle2) * step 5: perform the measurement measurepairs (SearchImage, MeasureHandle1, 2, 25, 'negative', 'all', RowEdge11, ColEdge11, Amp11, RowEdge21, ColEdge21, Amp21, Width1, Distance1) measurepairs (SearchImage, MeasureHandle2, 2, 25, 'negative', 'all', RowEdge12, ColEdge12, Amp12, RowEdge22, ColEdge22, Amp22, Width2, Distance2) closemeasure (MeasureHandle1) closemeasure (MeasureHandle2) endif * step 6: check for too short or missing teeth NumberTeeth1 := |Width1| NumberTeeth2 := |Width2| devsetcolor ('red') if (NumberTeeth1 < 37) for j := 0 to NumberTeeth1 - 2 by 1 if (Distance1[j] > 4.0) RowFault := round(0.5 * (RowEdge11[j + 1] + RowEdge21[j])) ColFault := round(0.5 * (ColEdge11[j + 1] + ColEdge21[j])) disprectangle2 (WindowHandle, RowFault, ColFault, 0, 4, 4) devopenwindow (0, Width + 20, 80, 80, 'black', WindowHandleZoom) devsetpart (RowFault - 10, ColFault - 10, RowFault + 10, ColFault + 10) devdisplay (SearchImage) disprectangle2 (WindowHandleZoom, RowFault, ColFault, 0, 4, 4) stop () devclosewindow () devsetpart (0, 0, Height - 1, Width - 1) endif endfor endif if (NumberTeeth2 < 37) for j := 0 to NumberTeeth2 - 2 by 1 if (Distance2[j] > 4.0) RowFault := round(0.5 * (RowEdge12[j + 1] + RowEdge22[j])) ColFault := round(0.5 * (ColEdge12[j + 1] + ColEdge22[j])) disprectangle2 (WindowHandle, RowFault, ColFault, 0, 4, 4) devopenwindow (0, Width + 20, 80, 80, 'black', WindowHandleZoom) devsetpart (RowFault - 10, ColFault - 10, RowFault + 10, ColFault + 10) devdisplay (SearchImage) disprectangle2 (WindowHandleZoom, RowFault, ColFault, 0, 4, 4) stop () devclosewindow () devsetpart (0, 0, Height - 1, Width - 1) endif endfor endif devsetcolor ('yellow') stop () endfor endif
  • ------------------- end of the application -----------------
  • clean up if (USINGTRANSLATEMEASURE != 0) closemeasure (MeasureHandle1) closemeasure (MeasureHandle2) endif devupdatewindow ('on') clearshapemodel (ModelID) ```

    机器人配合

在我们做完酒店标定以后,机器人只需要将视觉传过来的坐标带入到随动坐标系中,这样就能够得到准确的随动坐标。

结束语

本次我们提升了包装的速率,后续我们将对整个产线都实行自动化的功能升级;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宋小童

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值