• #maker+t=market
  • 3D列印服務
  • COSPLAY 3D 建模
  • 1
  • 2
  • 3

Python人工智慧圖控 - 研習交流廳 造訪社團 » CAM

原文網址 石小川
2020-03-22 15:02:17

近期為了ROS(機器人作業系統)相關專案,於是想起了以前的小玩具 - ROVIO,塵封已久的路威機器人在倉庫找了許久,終於抓到這隻小烏龜了,檢查電池、發現零組件狀況不錯,可見保存很好,這個ROVIO機器人麻雀雖小卻五臟俱全,看看下面硬體規格就知道。分享給有興趣製作機器人的朋友做參考。 Rovio機器人主要特點: 內含麥克風及喇叭可以雙向語音交談 可以遙控攝影機頭上下移動 可以手機和電腦或者Pad遠程網路控制 可以自動充電 雷達偵測障礙 硬體規格: 是以三大電路板結合而成:
(1)主ARM 板
Main Processor —科宇KOI-MP802 蓋面
實際為華邦 W99702 內建mpeg壓縮 跑 WEB server ,rtsp , and 主機總控
制 "spook" media streaming server ( [Spook Live Video Streamer]
( http://www.litech.org/spook/ ) )
Clock frequency 200Mhz
Main Memory — 8MB RAM
USB ttl port 與電腦通訊 (以W99100DG實現,負責isp下載)
Audio chip WM8976
Web cam video chip OV7670
SPI FLASH(W25X16) 2MB
OS Open-source "eCos" (2)充電電路板:專用NiMH充電管理芯片LS2516,PWM恆流方式,
電流不詳,穩壓二極體用的是1N5822,估計>1A。 (3)驅動板 MCU:4路BJT H電橋,3個輪子用光柵反饋,攝像頭升降用
可變電阻反饋,紅外線訊號和主控板通過串口通訊。 自動導航電路以紅外線感應運算
充電基座會投射出紅外線導航點,車上再以紅外線感應器做幾何
定位.定位程式由專門晶片負責.再送出串口訊號回應給上位機定位訊息

海闊天
2020-03-22 15:42:03

這台夢幻超跑要賣多少錢啊?小川哥!

海闊天
2020-03-22 15:42:32

海闊天
2020-03-22 15:42:44

石小川
2020-03-22 17:31:46

2013年露天買的, 3000多台幣, 拿來解剖研究用! 哈哈!

詹俊英
2020-03-24 20:58:27


原文網址 石小川
2020-03-07 18:57:10

當相同類型的程式時常使用或必須重複呼叫時,這時就是考慮將副程式加進程式庫的時候,我習慣將功能相同的函式放在一起製作專用的程式庫,例如處裡影像副程式放在TImage.dll、處裡語音副程式放在
TSpeech.dll、處裡神經網路程式放在TNeuron.dll、處裡光達程式放在TLidar.dll等等 , 一旦你的程式庫累計的夠多的話,將來設計APP應用程式就會如同貼圖一樣方便,只要呼叫程式庫就好,主程式變少了。 接下來Demo一個動態程式庫TSystem.dll,裡面函式是負責儲存使用者最後操作各個視窗元件位置及大小的資訊, 請一步步看圖解。 step1. 建立新的專案。 圖1 ? step2. 選 C#類別庫, 按下一步。 圖2 ? step3. 設定新的專案, 並按建立。 圖3 ? step4. 設計程式碼TSystem.cs。
//----------------------------------------------------------------------
//動態程式庫 TSystem.dll 範例
//---------------------------------------------------------------------- using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Drawing; namespaceTSystem
{
public class WindowPosition
{
//---------------------------------------------------------------------
public void WriteSystemInfo(string FileName, Point position)
{
BinaryWriter WriteFile = new BinaryWriter(File.Open(FileName,
FileMode.Create));
WriteFile.Write(position.X);
WriteFile.Write(position.Y);
WriteFile.Close();
} //------------------------------------------------------------------------
public Point ReadSystemInfo(string FileName)
{
if(!File.Exists(FileName))
return new Point(-1, -1);

BinaryReader ReadFile = new BinaryReader(File.Open(FileName,
FileMode.Open));
Point position = new Point(ReadFile.ReadInt32(),
ReadFile.ReadInt32());
ReadFile.Close();

return position;
} } //public class WindowPosition //-------------------------------------------------------------------------
public class WindowhSize
{
//---------------------------------------------------------------------
public void WriteSystemInfo(string FileName, Size size)
{
BinaryWriter WriteFile = new BinaryWriter(File.Open(FileName,
FileMode.Create)); //main form size
WriteFile.Write(size.Width);
WriteFile.Write(size.Height);
WriteFile.Close();
}

//------------------------------------------------------------------------
public Size ReadSystemInfo(string FileName)
{
if(!File.Exists(FileName))
return new Size(-1, -1);

BinaryReader ReadFile = new BinaryReader(File.Open(FileName,
FileMode.Open));
Size size = new Size(ReadFile.ReadInt32(), ReadFile.ReadInt32());
ReadFile.Close();

return size;
} } //public class WindowSize
} //namespace TSystem step5. 建置方案, 產生TSystem.dll。 圖4 ? step6. 產生的TSystem.dll的檔案及路徑。 圖5 ? step7. 主程式呼叫TSystem.dll, 需將產生的TSystem.dll加入參考。 圖6 ? step8. 主程式呼叫TSystem.dll( 關注//Note的地方即可 )。
//----------------------------------------------------------------------
//C# 主程式呼叫動態程式庫 TSystem.dll 範例
//----------------------------------------------------------------------
using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging; using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.CV.Util;
using Emgu.Util;
using Emgu.CV.UI;
using Emgu.CV.BgSegm;
using Emgu.CV.VideoSurveillance; //Note
using TSystem;
using TCamera; //-----------------------------------------------------------------------------
namespace VT
{
public partial class MainForm : Form
{
//---------------------------------------------------------------------
public ToolboxForm CreateToolboxForm(Form parent, string text,
bool bshow = true)
{
ToolboxForm toolboxForm;
toolboxForm = new ToolboxForm();
toolboxForm.MdiParent = parent;
toolboxForm.Text = text; if(bshow)
toolboxForm.Show();

return toolboxForm;
}

//---------------------------------------------------------------------
public ImageXYForm CreateImageXYForm(Form parent, int number,
stringtext, bool bshow = true)
{
ImageXYForm imageForm;
imageForm = new ImageXYForm(number);
imageForm.MdiParent = parent;
imageForm.Text = text;

if(bshow)
imageForm.Show();

return imageForm;
}

//---------------------------------------------------------------------
public static MainForm _gmainForm = null;
public static ToolboxForm _gtoolboxForm = null;
public static ImageXYForm _gimageXYForm = null;

//Note
public WindowhSize _winSize = null;

//---------------------------------------------------------------------
//Main Program
//---------------------------------------------------------------------
public MainForm()
{
InitializeComponent();
}

//---------------------------------------------------------------------
private void MainForm_Load(objectsender, EventArgs e)
{
_gmainForm = this;

//Note
//讀取系統設定檔
_winSize = new WindowhSize();
Size size = _winSize.ReadSystemInfo(@"..\..\system\mainform.inf");
if(size.Width == -1 && size.Height == -1)
this.ClientSize = new Size(1200, 700);
else
this.ClientSize = new Size(size.Width, size.Height);

//修改mdi窗体背景色--------------------------------------------------------
MdiClient ctlMDI;

// Loop through all of the form's controls looking
foreach(Control ctl in this.Controls)
{
try
{
// Attempt to cast the control to type MdiClient.
ctlMDI = (MdiClient) ctl;

// Set the BackColor of the MdiClient control.
ctlMDI.BackColor = Color.LightGray; //this.BackColor; //Color.Blue;
}
catch(InvalidCastException)
{
// Catch and ignore the error if casting failed.
}
}

_gtoolboxForm = CreateToolboxForm(this, "工具箱");
_gimageXYForm = CreateImageXYForm(this, 0, "XY軸攝影機");
} //private void MainForm_Load(object sender, EventArgs e)

//--------------------------------------------------------------------- private void MainForm_FormClosed(object sender,
FormClosedEventArgs e)
{
//Note
_winSize.WriteSystemInfo(@"....\system\mainform.inf",
new Size(this.ClientSize.Width, this.ClientSize.Height));
}
} //public partial class MainForm : Form
} //namespace VT step9. 執行主程式成功。
圖7 ?


原文網址 石小川
2020-03-01 19:04:55

程式可控制的參數例如圖像尺寸(ROI)、拍照、曝光時間、GAMMA、對比差、亮度、自定義LUT、鏡頭翻轉、RGB顏色增益、飽和度、銳度、彩色轉黑白、色溫校正、反色、9組十字線位置和顏色、觸發模式、幀率控制,有附SDK及C#、C++ Builder、Delphi、labView、QT5、VB、VC等範例可參考,對於喜歡寫自動控制程式的人來說非常方便。

usingSystem;

usingSystem.Collections.Generic;

usingSystem.ComponentModel;

usingSystem.Data;

usingSystem.Drawing;

usingSystem.Linq;

usingSystem.Text;

usingSystem.Threading.Tasks;

usingSystem.Windows.Forms;

usingSystem.Runtime.InteropServices;

usingSystem.Threading;

usingCameraHandle = System.IntPtr;

usingCKSDK;

usingCKAPI = CKSDK.CKSDKAPI;

namespacePlayer

{

public partial class mainwindow: Form

{

# regionvariable

protectedCameraHandle m_hCamera = IntPtr.Zero; // 句柄

protectedThread m_CapThread;

protected boolm_bExit = false;

protected uintm_uWidth = 0;

protected uintm_uHeight = 0;

doublem_CapFrameRate = 0;

doublem_DisFrameRate = 0;

# endregion

public mainwindow()

{

InitializeComponent();

CameraRefresh();

}

public voidCaptureThreadFunction()

{

stImageInfo ImageInfo = newstImageInfo();

CameraSdkStatus status = CameraSdkStatus.CAMERA_STATUS_SUCCESS;

IntPtr pRGBFrame = IntPtr.Zero;

uintDispFrameNum = 0;

intFrameTimeCur = 0;

intFrameTimeLast = 0;

FrameStatistic curFS = newFrameStatistic();

FrameStatistic lastFS = newFrameStatistic();

IntPtr pbyBuffer = IntPtr.Zero;

uintdRGBBufLen = 0;

CameraHandle hBuf = IntPtr.Zero;

CKAPI.CameraPlay(m_hCamera);

while(!m_bExit)

{

CKAPI.CameraGetFrameStatistic(m_hCamera, outcurFS);

if(FrameTimeCur != 0)

{

FrameTimeCur = Environment.TickCount;

intdeltime = FrameTimeCur - FrameTimeLast;

if(1000 <= deltime)

{

m_CapFrameRate = (double)(((double)curFS.iCapture - (double)lastFS.iCapture) * 1000.0) / deltime;

m_DisFrameRate = (double)DispFrameNum * 1000.0 / deltime;

lastFS = curFS;

FrameTimeLast = FrameTimeCur;

DispFrameNum = 0;

}

}

else

{

FrameTimeCur = Environment.TickCount;

FrameTimeLast = FrameTimeCur;

lastFS = curFS;

}

//获取 RAW 数据

status = CKAPI.CameraGetRawImageBuffer(m_hCamera, refhBuf, 1000);

if(status != CameraSdkStatus.CAMERA_STATUS_SUCCESS)

{

Thread.Sleep(5);

continue;

}

//获得图像缓冲区地址

pbyBuffer = CKAPI.CameraGetImageInfo(m_hCamera, hBuf, refImageInfo);

//获得经 ISP 处理的 RGB 数据

//////////////////////////////////

if(dRGBBufLen < (ImageInfo.iWidth * ImageInfo.iHeight * 4))

{

dRGBBufLen = (ImageInfo.iWidth * ImageInfo.iHeight * 4);

pRGBFrame = Marshal.AllocHGlobal(Convert.ToInt32(dRGBBufLen));

}

m_uWidth = ImageInfo.iWidth;

m_uHeight = ImageInfo.iHeight;

CKAPI.CameraGetOutImageBuffer(m_hCamera, refImageInfo, pbyBuffer, pRGBFrame);

DispFrameNum++;

//////////////////////////////////显示

CKAPI.CameraDisplay(m_hCamera, pRGBFrame, refImageInfo);

//释放由 CameraGetRawImageBuffer 获得的缓冲区

CKAPI.CameraReleaseFrameHandle(m_hCamera, hBuf);

}

CKAPI.CameraPause(m_hCamera);

}

private voidCameraRefresh()

{

// 清空设备combobox

this.comboBox_DeviceList.Items.Clear();

CameraSdkStatus status;

//tSdkCameraDevInfo[] tCameraDevInfoList;

intdevNum = 0;

status = CKAPI.CameraEnumerateDevice(refdevNum);

if(status != CameraSdkStatus.CAMERA_STATUS_SUCCESS)

return;

for(inti = 0; i < devNum; i++)

{

tDevEnumInfo devAllInfo;

// 获取设备信息

status = CKAPI.CameraGetEnumIndexInfo(i, outdevAllInfo);

if(status != CameraSdkStatus.CAMERA_STATUS_SUCCESS)

continue;

// 将设备昵称增加到combobox控件中。

this.comboBox_DeviceList.Items.Add(new string(devAllInfo.DevAttribute.acFriendlyName));

}

if(devNum > 0)

this.comboBox_DeviceList.SelectedIndex = 0;

}

private voidCameraSetting()

{

if(m_hCamera != IntPtr.Zero)

{

if(CKAPI.CameraSetActivePage(m_hCamera, emSettingPage.SETTING_PAGE_ALL, 0) != CameraSdkStatus.CAMERA_STATUS_SUCCESS)

return;

if(CKAPI.CameraCreateSettingPageEx(m_hCamera) != CameraSdkStatus.CAMERA_STATUS_SUCCESS)

return;

CKAPI.CameraShowSettingPage(m_hCamera, 1);

}

}

private boolCameraPlay()

{

// 先停止当前的播放,然后再打开新的播放设备

CameraStop();

intindex = this.comboBox_DeviceList.SelectedIndex;

if(index < 0)

return false;

// 初始化设备,返回设备句柄

CameraSdkStatus status = CKAPI.CameraInit(refm_hCamera, index);

if(status != CameraSdkStatus.CAMERA_STATUS_SUCCESS)

{

m_hCamera = IntPtr.Zero;

return false;

}

// 初始化播放显示,设置显示图像的控件句柄

status = CKAPI.CameraDisplayInit(m_hCamera, this.pictureBox.Handle);

if(status != CameraSdkStatus.CAMERA_STATUS_SUCCESS)

{

CKAPI.CameraUnInit(m_hCamera);

m_hCamera = IntPtr.Zero;

return false;

}

// 新建视频播放线程

m_bExit = false;

m_CapThread = newThread(newThreadStart(CaptureThreadFunction));

m_CapThread.Start();

return true;

}

private voidCameraStop()

{

// 先关闭线程

if(m_CapThread != null)

{

m_bExit = true;

while(m_CapThread.IsAlive)

Thread.Sleep(10);

m_CapThread = null;

}

// 关闭相机句柄

if(m_hCamera != IntPtr.Zero)

{

CKAPI.CameraUnInit(m_hCamera);

m_hCamera = IntPtr.Zero;

}

}

private voidbutton_Refresh_Click(objectsender, EventArgs e)

{

CameraRefresh();

}

private voidbutton_PlayOrStop_Click(objectsender, EventArgs e)

{

if(this.button_PlayOrStop.Text == "Play")

{

if(CameraPlay())

{

this.button_PlayOrStop.Text = "Stop";

this.button_Setting.Enabled = true;

this.timer_DevInfo.Start();

}

}

else

{

CameraStop();

this.button_PlayOrStop.Text = "Play";

this.button_Setting.Enabled = false;

this.timer_DevInfo.Stop();

}

}

private voidbutton_Setting_Click(objectsender, EventArgs e)

{

CameraSetting();

}

private voidtimer_DevInfo_Tick(objectsender, EventArgs e)

{

this.label_DevInfo.Text = string.Format("resolution: {0} x {1} | capture frame rate: {2:###.##} | display frame rate: {3:###.##}",

m_uWidth, m_uHeight, m_CapFrameRate, m_DisFrameRate);

}

private voidForm1_FormClosing(objectsender, FormClosingEventArgs e)

{

CameraStop();

}

}

}

翻譯年糕


原文網址 石小川
2020-01-04 23:08:58

分享早期做過開源3D掃描器的軟硬體資料給有興趣的朋友們參考,這裡面的掃描演算法就是3D光學雷達的一種,大小掃描器我都製作成功,挺有趣的,過程可學習到軟硬體及光學調校經驗,有實作問題可提出大家討論。

1. 大台3D 掃描器零組件如下(BOM):

(1)鋁擠 640 x 640 x 640mm x 1
(2)雷射頭(5V/5mW) x 2
(3)Logitec C270 Camera x1
(4)42步進馬達驅動的旋轉台 x 1
(5)Arduino UNO + CNC v3 Shield x 1
(6)電源供應器 DC 12V/350W (可拿廢棄電腦電源供應器代替) x 1

因為整個架構是非標準型的Horus CIC Lop, 想要掃描大型物件, 所以軟體部分需要修改Horus 和 Marlin的一些參數, 調校參數也比較花功夫些, 好玩的是Horus是用Python寫的, 可以自行外加一些自行設計的演算法如數位濾波器, 提高掃描影像品質。

2. 小台3D 掃描器零組件如下(BOM):

除了機台需用3D列印外,其餘的與大台零組件相同,如圖。

p.s. 因為檔案豐富有點多,包含安裝說明、Arduino燒寫程式、PC端APP等,容我慢慢上傳!

因臉書限制上傳一些檔案,需要完整程式的朋友請留訊息給我直接用雲端傳。


原文網址 石小川
2019-12-15 17:44:44

對於Linux工程師來說內嵌系統交叉編譯環境的建立較複雜, 手動編譯起來時常是一個噩夢, 其實只要資料完備不會很困難, 下面我把一些講義分享出來給有需要的好友參考一下, 期望可以少走一些冤枉路! 我PC的Linux作業系統版本是Fedora 20-i386, Embedded system 是ARM11板子的內嵌系統, 我在PC開發的程式是Qt5.4.1, opencv是3.1.0, PC開發環境下寫好的程式再移植到ARM11板子上, 可正常運作, 沒圖沒真相, 如圖程式是usb camera程式, 可顯示JPG照片及動態顯示攝影機視訊! 由於QT 及 OpenCV arm-linux交叉編譯比較冗長, 我再另闢專欄解說, 這之前我先列出交叉編譯需要用到的一些程式庫的編譯詳細步驟, 有不清楚的地方也可跟我討論一下! //-------------------------------------------------------------------------------
Linux交叉編譯環境建立 講義 交叉編譯(Cross compiler)是在一種處理器架構平台上(如PC-x86架構,此稱PC平台)編譯連結成另一個處理器架構平台(如ARM架構,此稱Target平台)所能執行程式的工具軟體。 A. PC-x86平台環境建立步驟
(1)Install Fedora 20
Download Linux OS,版本為Fedora20-i386-DVD.iso,燒寫
至光碟片,然後安裝作業系統到PC。
先更新作業系統。
yum update -y (2)Install Fedora 20相關工具軟體
yum install –y filezilla putty cmake cmake-gui gcc gcc-c++
yum install –y automake libtool tslib (3)Install arm-linux-gcc
(3-1)解壓縮arm-linux-gcc-4.5.1-v6-vfp-20101103.tgz
執行Fedora 20>>終端機程式,輸入:
tar xvzf arm-linux-gcc-4.5.1-v6-vfp-20101103.tgz –C /opt/,解壓縮將arm-linux-gcc-4.5.1安裝到/opt/FriendlyARM/toolschain/4.5.1。
p.s. 路徑一定要放在此(/opt/),不能更改,否則會錯誤。
(3-2)將arm-linux-gcc的路徑加到系統環境變數中
method 1. 修改檔案.bashrc(個人環境)
用vi 編輯 /root/.bashrc
最後一行加上:
export PATH=$PATH:/opt/FriendlyARM/toolschain/4.5.1/bin
儲存後OS重新登錄User即可作用。
method 2. 修改檔案 /etc/profile(全域環境)
最後一行加上:
export PATH=$PATH:/opt/FriendlyARM/toolschain/4.5.1/bin
儲存後須重新開機始可作用。
(3-3)在終端機輸入arm-linux-gcc –v,如果有gcc相關資訊顯示出來表示設定成功。 (4)交叉編譯相關程式庫
如果沒用到可選擇跳過不安裝,詳細交叉編譯方法請看附錄A。
(4-1)交叉編譯tslib
觸控面板驅動函式庫。
(4-2)交叉編譯ffmpeg
影片播放與轉檔函式庫。
(4-3)交叉編譯gtk
圖形介面開發套件。
(4-4)交叉編譯jpeg
Jpeg功能函式庫。
(4-5)交叉編譯png
Png功能函式庫。
(4-6)交叉編譯x264
X264編碼器函式庫。
(4-7)交叉編譯yasm
編譯ffmpeg時可指定用yasm指令編譯,提高編譯速度。
(4-8)交叉編譯zlib
資料壓縮函式庫。
(4-9)交叉編譯qt5.4.1
跨平台的c++應用程式開發工具。 (5)Install Qt Creator
到Qt官方網站:
https://www.qt.io/download-open-source/#section-2
選擇下載Qt Online Installer for Linux 32-bit 線上安裝Qt Creator相關程式。安裝程式會自動安裝PC平台的Qt,至於Target平台的Qt必須手動交叉編譯來安裝。
(為求系統穩定,盡量以Qt 5.4.1為開發版本。) (6)Install Opecv
到Opencv官方網站:
http://opencv.org/downloads.html
選擇下載Opencv-3.1.0.zip 附錄A
A-1. 交叉編譯tslib
功能: 觸控面板驅動函式庫。
在終端機按照步驟輸入指令如下:
(1)git clone https://github.com/kergoth/tslib
//download tslib source code
(2) cp /root/tslib /opt/ -r
//copy /root/tslib to /opt
(3)cd /opt/tslib
//change dir to /tslib
(4)./autogen.sh
//執行安裝腳本
(5) ./configure CC=arm-linux-gcc CXX=CC=arm-linux-g++ --prefix=/opt/tslib-arm --host=arm-linux ac_cv_func_malloc_0_nonnull=yes
//配置tslib
(5) make
//產生makefile
(6) make install
//編譯完成後函示庫自動安裝到 /opt/tslib-arm A-2. 交叉編譯zlib
功能: 提共資料壓縮之用的函式庫。
在終端機按照步驟輸入指令如下:
(1) download and copy zlib-1.2.8 to /opt
(2) cd /opt/ zlib-1.2.8
(3) CC=arm-linux-gcc ./configure --prefix=/opt/zlib-arm
(4) make
(5) make install A-3. 交叉編譯jpeg
功能: jpeg函式庫。
在終端機按照步驟輸入指令如下:
(1) download and copy jpeg-9 to /opt
(2) cd /opt/ jpeg-9
(3) CC=arm-linux-gcc ./configure --prefix=/opt/jpeg9-arm -- host=arm-linux
(4) make
(5) make install A-3. 交叉編譯png
功能: png函式庫。
在終端機按照步驟輸入指令如下:
(1) download and copy libpng-1.6.23 to /opt
(2) cd /opt/ libpng-1.6.23
(3) ./configure CC=arm-linux-gcc --prefix=/opt/png-arm -- host=arm-linux
(4) make
(5) make install A-4. 交叉編譯yasm
功能: yasm指令可提高編譯ffmpeg速度。
在終端機按照步驟輸入指令如下:
(1)download and copy yasm-1.3.0 to /opt
(2)cd /opt/ yasm-1.3.0
(3)./configure CC=arm-linux-gcc --prefix=/opt/yasm-arm --host=arm-linux
(4)make
(5)make install A-5. 交叉編譯x264
功能: x264編碼器函式庫。
在終端機按照步驟輸入指令如下:
(1)download and copy x264-snapshot-20160220-2245-stable to /opt
(2)cd /opt/x264-snapshot-20160220-2245-stable
(3)./configure CC=arm-linux-gcc --enable-shared --host=arm-linux --disable-asm --prefix=/opt/x264-arm
(4)make
(5)make install A-6. 交叉編譯ffmpeg
功能: 影片播放與轉檔函式庫。
在終端機按照步驟輸入指令如下:
(1) download and copy ffmpeg-3.1.1 to /opt
(或直接下載: git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg)
(2)cd /opt/ ffmpeg-3.1.1
(3)./configure --enable-cross-compile --cc=arm-linux-gcc --arch=arm --target-os=linux --enable-shared --enable-gpl --disable-stripping --enable-pthreads --enable-small --disable-parsers --disable-optimizations --disable-yasm --disable-armv6 --disable-static --disable-amd3dnow --prefix=/opt/ffmpeg-arm
(4)make
(5)make install

Jade Yang
2019-12-15 18:43:39

林永仁
2019-12-16 09:09:29


原文網址 石小川
2019-11-27 10:57:00

對於想用CNC製作一些零組件的朋友來說,要學會AutoCAD、SolidWork、uG、Fusion360、ARTCAM、PowerMill、 MasterCAM、Mach3等,我相信會嚇跑一票人的熱血。其實CAD/CAM套裝軟體很強但有很多功能幾百年也用不到,只是浪費錢而已,在接工廠自動控制客製化軟體方面絕大部分作動都很單純,我這裡是將所有功能精簡成 : /檔案/機器/刀具/G-Code sender,只要讀檔或在螢幕寫字、繪圖後自動產生G-Code直接送至CNC銑床或雷射加工,盡量能由機器代勞的就盡量隱藏在程式裏面,操作介面就只有一個螢幕面板Panel。

要做到這點須先解析DWG檔案結構,後續追加功能才有辦法走下去,AutoCAD DWG檔案簡直就是一個複雜的巨型圖層資料庫而且每兩年改版一次,建議還是用DXF圖檔相容性較高,有機會再談談DXF檔結構。這裡先分享一下DWG解析方法給有興趣研發的好友參考一 下。

基本上程式要解析其中的資料結構如下,有點長刪減一些函數但原理不變。

讀取DWG檔後打開資料庫取實體EntityName的字串名稱(約50個標籤名稱)一層層解析後繪圖即可原圖重現,看你要加圖、刪圖或送去產生G-Code等,另外如果用不著的功能就略過,沒必要全部實作,有興趣可一起討論,下回再討論G-Code產生器。

p.s. 下列範例是C#版本,有興趣的朋友歡迎自行改成Python版本。

//-------------------------------------------------------------------
public void Draw(List<CadParse> cadparselist)
{
foreach(CadParse cadParse in cadparselist)
{
switch(cadParse.EntityName)
{
case "AcDbAlignedDimension":
break;
case "AcDbArc":
break;
case "AcDbArcDimension":
break;
case "AcDbBlockReference":
break;
case "AcDbBody":
break;
case "AcDbCircle":
DrawCircle(cadParse);
break;
case "AcDbPoint":
break;
case "AcDbDiametricDimension":
break;
case "AcDbViewport":
break;
case "AcDbEllipse":
DrawEllipse (cadParse);
break;
case "AcDbFace":
break;
case "AcDbHatch":
break;
case "AcDbLeader":
break;
case "AcDbLine":
DrawLine(cadParse);
break;
case "AcDb2LineAngularDimension":
break;
case "AcDbMInsertBlock":
break;
case "AcDbMline":
break;
case "AcDbMText":
break;
case "AcDbOle2Frame":
break;
case "AcDbOrdinateDimension":
break;
case "AcDb3PointAngularDimension":
break;
case "AcDbPolyFaceMesh":
break;
case "AcDbPolygonMesh":
break;
case "AcDbPolyline":
DrawPolyLine(cadParse);
break;
case "AcDb2dPolyline":
break;
case "AcDb3dPolyline":
break;
case "AcDbProxyEntity":
break;
case "AcDbRadialDimension":
break;
case "AcDbRasterImage":
break;
case "AcDbRay":
break;
case "AcDbRegion":
break;
case "AcDbRotatedDimension":
break;
case "AcDbShape":
break;
case "AcDbSolid":
break;
case "AcDb3dSolid":
break;
case "AcDbSpline":
break;
case "AcDbTable":
break;
case "AcDbTrace":
break;
case "AcDbWipeout":
break;
case "AcDbXline":
break;
case "AcDbPdfReference":
break;
case "AcDbDwfReference":
break;
case "AcDbDgnReference":
break;
} //end switch(cadParse.EntityName)
} //end foreach(CadParse cadParse in _cadParseList)
} //end public void Draw()


原文網址 石小川
2019-11-27 10:39:11

雙眼攝影機測距 I – 設備實體製作(像蛙鏡,就稱蛙鏡好了)

其實這個就是光學雷達(Lidar)的一種。在機器人視覺中模擬人眼雙目測距是最基本功夫,而且設備簡單只要兩個攝像頭加上演算法即可實現測距,沒有雷射輔助的話10公尺的誤差在1公分以內, 算是可接受範圍,精準度要看個人調校技巧了,加上雷射光或其他結構光輔助更可進一步將RGB影像加上深度資訊,換句話說就是上回談到的點雲圖了,這對機器人視覺來說太有用了。

在研讀聚合物(Polymer)時,對於壓克力的物理化學特性就深受其吸引,所以做產品或實驗時常拿壓克力練功。 因為壓克力有易碎特性,此次用CNC銑時參數調慢些, 轉速S6000, 進給F300, 每層下切0.5mm,成果還不錯只是慢了些花了兩個鐘頭,下次實驗再調快否則有點大材小用,對不起這台專門銑不銹鋼模具的機器。

圖示是實作的設備,兩個攝像頭(Camera x 2) + 一個雷射頭(Laser x 1),外加演算法,就這麼簡單! 至於雙眼測距原理就是上童軍課的三角測距法,下回 “雙眼攝影機測距 I I – 原理解析” 再來聊聊了^^


 

全不選 發文排行