【上海晶珩睿莓 1 單板計(jì)算機(jī)】人臉識(shí)別
本文介紹了上海晶珩睿莓 1 單板計(jì)算機(jī)結(jié)合 OpenCV 內(nèi)置 YuNet 算法和 SFace 模型實(shí)現(xiàn)人臉識(shí)別的項(xiàng)目設(shè)計(jì),包括環(huán)境部署、預(yù)訓(xùn)練模型獲取
2026-01-04 20:22:01
近日,奕斯偉計(jì)算與全球開(kāi)源操作系統(tǒng)領(lǐng)軍企業(yè)Canonical簽署授權(quán)許可協(xié)議, 奕斯偉計(jì)算EBC77系列硬件產(chǎn)品——SBC單板計(jì)算機(jī)、Mini-DTX主板, 正式獲得Ubuntu操作系統(tǒng)安裝許可
2025-12-26 09:10:21
607 
12月5日,由中國(guó)圖象圖形學(xué)學(xué)會(huì)青年工作委員會(huì)(下簡(jiǎn)稱“青工委”)、上海市計(jì)算機(jī)學(xué)會(huì)計(jì)算機(jī)視覺(jué)專(zhuān)委會(huì)(下簡(jiǎn)稱“專(zhuān)委會(huì)”)聯(lián)合主辦,上海西井科技股份有限公司、江蘇路街道商會(huì)承辦的“上海計(jì)算機(jī)視覺(jué)企業(yè)行—走進(jìn)西井科技”學(xué)術(shù)沙龍,在西井科技武夷路上??偛宽樌e行。
2025-12-16 15:39:30
385 電子發(fā)燒友網(wǎng)報(bào)道(文/吳子鵬)日前,中國(guó)首個(gè)規(guī)?;瘜?zhuān)用光量子計(jì)算機(jī)制造工廠在深圳南山智城正式啟用,我國(guó)量子計(jì)算產(chǎn)業(yè)迎來(lái)了歷史性時(shí)刻——這不僅是國(guó)內(nèi)首個(gè)光量子計(jì)算機(jī)規(guī)?;圃旎氐恼Q生,更標(biāo)志著中國(guó)在
2025-11-28 08:21:00
7421 據(jù)央視新聞報(bào)道;在24日;深圳南山區(qū)國(guó)內(nèi)首個(gè)光量子計(jì)算機(jī)制造工廠正式進(jìn)入小規(guī)模生產(chǎn)階段,據(jù)悉該工廠是隸屬于玻色量子;總面積約5000平方米,集研發(fā)、制造、測(cè)試于一體,用于實(shí)現(xiàn)光量子計(jì)算機(jī)的工程化、標(biāo)準(zhǔn)化和規(guī)?;a(chǎn)。第一臺(tái)計(jì)算能力達(dá)到1000個(gè)量子比特的光量子計(jì)算機(jī)在這里生產(chǎn)。 ?
2025-11-25 17:17:37
1871 在工業(yè)自動(dòng)化和智能制造領(lǐng)域,計(jì)算機(jī)設(shè)備作為核心控制單元,其選擇直接影響整個(gè)系統(tǒng)的穩(wěn)定性與可靠性。工控機(jī)與普通計(jì)算機(jī)雖同屬計(jì)算設(shè)備,但其設(shè)計(jì)目標(biāo)、性能側(cè)重和應(yīng)用場(chǎng)景存在根本性差異。準(zhǔn)確理解這些差異,是進(jìn)行正確設(shè)備選型的基礎(chǔ)。
2025-11-25 14:45:53
1553 
電子發(fā)燒友網(wǎng)綜合報(bào)道 2025年11月14日,中國(guó)電信量子研究院正式宣布,搭載“祖沖之三號(hào)”同款芯片的超導(dǎo)量子計(jì)算機(jī)“天衍-287”完成搭建。這一突破標(biāo)志著我國(guó)首個(gè)具備“量子計(jì)算優(yōu)越性”的量子計(jì)算云
2025-11-18 08:40:00
8334 
不同客戶對(duì)高性能信創(chuàng)嵌入式計(jì)算機(jī)的多樣化需求。
[]()
BPI - 2K3000可應(yīng)用于企業(yè)辦公、個(gè)人微型計(jì)算機(jī)、高性能工業(yè)計(jì)算機(jī),以及教育、醫(yī)療、金融、邊緣計(jì)算等領(lǐng)域。它具有高性能計(jì)算、便攜、低能耗和易
2025-11-15 11:43:19
2025年11月8日,由教育部計(jì)算機(jī)類(lèi)專(zhuān)業(yè)系統(tǒng)能力課程群虛擬教研室指導(dǎo)、北京航空航天大學(xué)計(jì)算機(jī)學(xué)院主辦的龍架構(gòu)計(jì)算機(jī)系統(tǒng)能力核心課程教學(xué)研討會(huì)在京舉行。
2025-11-14 13:52:01
516 近日,2025中國(guó)工業(yè)計(jì)算機(jī)大會(huì)(CCF ICCC 2025)在云南昆明召開(kāi)。本次大會(huì)由中國(guó)計(jì)算機(jī)學(xué)會(huì)主辦,中國(guó)計(jì)算機(jī)學(xué)會(huì)工業(yè)控制計(jì)算機(jī)專(zhuān)委會(huì)、國(guó)家工業(yè)控制機(jī)及系統(tǒng)工程技術(shù)研究中心和昆明
2025-11-10 17:35:57
561 貿(mào)澤電子開(kāi)售全新Arduino UNO Q單板計(jì)算機(jī)。Arduino UNO Q單板計(jì)算機(jī)(SBC)將高性能計(jì)算與實(shí)時(shí)控制結(jié)合,提供理想的創(chuàng)新平臺(tái)。
2025-11-08 09:50:05
1146 近日,備受矚目的第22屆中國(guó)計(jì)算機(jī)大會(huì)(CNCC2025)在哈爾濱開(kāi)幕。本屆大會(huì)注冊(cè)人數(shù)突破1.2萬(wàn)人,匯聚了來(lái)自全球計(jì)算機(jī)領(lǐng)域的頂尖學(xué)者、產(chǎn)業(yè)領(lǐng)袖、青年學(xué)子及國(guó)際組織代表。大會(huì)以“數(shù)智賦能、無(wú)限可能”為主題,旨在深度探討數(shù)字智能技術(shù)的前沿進(jìn)展與未來(lái)趨勢(shì),為推動(dòng)計(jì)算技術(shù)與經(jīng)濟(jì)社會(huì)深度融合貢獻(xiàn)智慧。
2025-11-02 09:29:53
499 10月23日至25日,第二十二屆中國(guó)計(jì)算機(jī)大會(huì)(CNCC2025)在哈爾濱成功舉辦。大會(huì)以“數(shù)智賦能,無(wú)限可能”為主題,匯聚了來(lái)自全球計(jì)算機(jī)領(lǐng)域的頂尖學(xué)者、產(chǎn)業(yè)領(lǐng)袖、青年學(xué)子及國(guó)際組織代表,共同探討
2025-10-27 17:46:36
796 在導(dǎo)航系統(tǒng)中,嵌入式計(jì)算機(jī)的核心作用是實(shí)時(shí)處理多種傳感器的數(shù)據(jù),運(yùn)行復(fù)雜的導(dǎo)航算法,最終計(jì)算出載體的精確位置、姿態(tài)、速度和時(shí)間信息。
2025-09-26 16:52:15
899 DGX Spark 現(xiàn)已開(kāi)啟預(yù)訂!麗臺(tái)科技作為 NVIDIA 授權(quán)分銷(xiāo)商,提供從產(chǎn)品到服務(wù)的一站式解決方案,助力輕松部署桌面 AI 計(jì)算機(jī)。
2025-09-23 17:20:50
1060 
全國(guó)產(chǎn)化導(dǎo)航計(jì)算機(jī)子卡是實(shí)現(xiàn)在國(guó)防、航天等國(guó)家關(guān)鍵領(lǐng)域技術(shù)自主的重要一環(huán)。
2025-09-16 18:02:30
698 
Gateworks采用u-blox GNSS RTK、校正服務(wù)和藍(lán)牙模塊,為應(yīng)用開(kāi)發(fā)者提供可應(yīng)對(duì)惡劣環(huán)境的可靠精準(zhǔn)定位與通信能力。
2025-09-15 14:09:38
616 千兆以太網(wǎng)端口用于充電的USB-C接口我很喜歡在較小的單板計(jì)算機(jī)(SBC)上看到以太網(wǎng)端口,因?yàn)檫@使它們作為瘦客戶端更有用,而且對(duì)于這種尺寸的單板計(jì)算機(jī)來(lái)說(shuō),充裕的
2025-09-12 13:44:26
897 
MUSE Pi Pro 單板計(jì)算機(jī)將 RISC-V 八核處理器、存儲(chǔ)硬盤(pán)、通用接口部件和擴(kuò)展接口布置在同一塊電路板上,支持 UEFI 啟動(dòng)以及多種操作系統(tǒng)和應(yīng)用的運(yùn)行,是一款完整的計(jì)算機(jī)系統(tǒng)產(chǎn)品
2025-09-11 10:01:46
北斗衛(wèi)星同步時(shí)鐘系統(tǒng):水電新能源計(jì)算機(jī)監(jiān)控系統(tǒng)
2025-09-10 15:00:51
540 
賽昉科技VisionFive 2單板計(jì)算機(jī)開(kāi)發(fā)板測(cè)評(píng)作品合集
產(chǎn)品介紹:
昉·星光 2是全球首款集成了3D GPU的高性能量產(chǎn)RISC-V單板計(jì)算機(jī),搭載昉·驚鴻-7110(型號(hào):JH-7110
2025-09-04 09:08:26
8月26日,elexcon2025深圳國(guó)際電子展在深圳會(huì)展中心隆重開(kāi)幕。在全球知名新品引入(NPI)代理商貿(mào)澤電子(Mouser Electronics) 展臺(tái)(1號(hào)館1Q30),DFRobot展示了其LattePanda Sigma單板計(jì)算機(jī)與Qwen3大語(yǔ)言模型的融合應(yīng)用。
2025-08-30 10:51:06
896 Banana Pi BPI-R4 Lite 現(xiàn)已上市。具體來(lái)說(shuō),這款單板計(jì)算機(jī)在 Youyeetoo 上的售價(jià)約為 86 美元,但客戶在下單前請(qǐng)務(wù)必查看運(yùn)輸條款和費(fèi)用。這是一款單板計(jì)算機(jī),有望成為
2025-08-26 16:46:28
1189 
加固計(jì)算機(jī)是一種專(zhuān)門(mén)為復(fù)雜環(huán)境和特殊行業(yè)應(yīng)用設(shè)計(jì)的高性能設(shè)備。它不僅具備常規(guī)電腦的數(shù)據(jù)處理和運(yùn)算功能,更在結(jié)構(gòu)設(shè)計(jì)、防護(hù)等級(jí)和硬件配置方面做了全面優(yōu)化。例如,它的外殼通常采用鎂鋁合金或高強(qiáng)度復(fù)合材料
2025-08-22 09:55:50
463 全志科技合作伙伴瑞莎計(jì)算機(jī)(Radxa) 今日發(fā)布基于全志 A733處理器平臺(tái)的單板計(jì)算機(jī)—— Cubie A7A。該產(chǎn)品將高性能計(jì)算、AI 加速能力與靈活的接口擴(kuò)展相結(jié)合,面向邊緣計(jì)算、人工智能
2025-08-20 11:37:36
2209 2025重磅消息!今年9月,樹(shù)莓派團(tuán)隊(duì)將首次亮相上海工博會(huì)(CIIF)。屆時(shí),現(xiàn)場(chǎng)將展示超多硬核科技:從樹(shù)莓派單板計(jì)算機(jī)(最高至RaspberryPi500)、RaspberryPiPico系列,到基于RP2350的解決方案,還有AI產(chǎn)品、攝像頭和前沿工業(yè)設(shè)備ComputeModule5
2025-08-15 19:36:55
892 
創(chuàng)建init
創(chuàng)建init.sh文件,并設(shè)置權(quán)限為root
sudo chown root init.sh
sudo chgrp root init.sh
init.sh文件中寫(xiě)入
#!/bin/bash
echo \"系統(tǒng)于
$(date) 開(kāi)機(jī)\" >> /var/log/myscript.log
cd /home/user/01_LCD/
python3 LCD_demo.py
配置啟動(dòng)服務(wù)
在 /etc/systemd/system/ 目錄下創(chuàng)建一個(gè) .service 文件(如 my.service)
并寫(xiě)入下述代碼
[Unit]
Description=My Custom Script
After=network.target
[Service]
Type=simple
ExecStart=/home/user/init.sh
User=root
[Install]
WantedBy=multi-user.target
添加服務(wù)
# 重新加載systemd配置
sudo systemctl daemon-reload
# 設(shè)置開(kāi)機(jī)自啟
sudo systemctl enable my.service
# 手動(dòng)測(cè)試服務(wù)是否正常運(yùn)行
sudo systemctl start my.service
驗(yàn)證是否生成
cat /var/log/myscript.log# 查看日志是否生成
然后重啟設(shè)備就可以看到開(kāi)機(jī)就會(huì)自動(dòng)顯示時(shí)間和圖片了
2025-08-14 22:04:29
倘若計(jì)算的未來(lái)并非被專(zhuān)有架構(gòu)所壟斷,那會(huì)怎樣?想象一下這樣一個(gè)世界:開(kāi)發(fā)者和業(yè)余愛(ài)好者都能利用開(kāi)源硬件的力量自由地構(gòu)建、創(chuàng)新和實(shí)驗(yàn)?,F(xiàn)在,讓我們走進(jìn)RISC-V單板計(jì)算機(jī)(SBC)的世界——一個(gè)正在
2025-08-14 13:37:51
869 
小結(jié)
電子相冊(cè)功能已完成,附帶一個(gè)日歷效果。
可以通過(guò)同局域網(wǎng)samba實(shí)現(xiàn)手機(jī)或者電腦直接將圖片傳到vf2中,并在代碼中設(shè)定輪流播放的時(shí)間。
記錄生活照片或者做成文物日歷。
基礎(chǔ)功能暫時(shí)告一段落。
使用感受:
vf2提供了python控制gpio接口,簡(jiǎn)化了驅(qū)動(dòng)的實(shí)現(xiàn)。
vf2的python實(shí)現(xiàn)很方便,直接調(diào)用庫(kù)實(shí)現(xiàn)圖片的等比放大,轉(zhuǎn)成想要的色深等等。
后續(xù)完全可以結(jié)合i2c等實(shí)現(xiàn)對(duì)應(yīng)傳感器數(shù)據(jù)的顯示,我就不在這里更新了。
此外還有一些遺憾
缺少wifi,始終需要使用網(wǎng)口
測(cè)試下來(lái),使用python將一張圖解析出來(lái)轉(zhuǎn)色深到lcd上,需要3s以上,之后我再基于同版參數(shù)和其他的開(kāi)發(fā)板做評(píng)估吧。
本打算實(shí)現(xiàn)音頻接口功能,由于時(shí)間有限,加上刷機(jī)有點(diǎn)沒(méi)弄明白,不是一次性刷到sd卡中,所以音頻的部分只能擱置。
人臉識(shí)別的部分以后再做吧,可以結(jié)合led燈陣做成寄存柜,之后項(xiàng)目再更新。
#!/usr/bin/python
\"\"\"
Please make sure the 2.4inch LCD Moudle is connected to the correct pins.
The following table describes how to connect the 2.4inch LCD Module to the 40-pin header.
-------------------------------------------------
__2.4inch LCD Module___Pin Number_____Pin Name
VCC173.3 V Power
GND39 GND
DIN19SPI MOSI
CLK23SPI SCLK
CS 13GPIO43y
DC 11GPIO42y-
RST07GPIO55y-
BL 15GPIO47y
-------------------------------------------------
\"\"\"
import os
import sys
import time
import logging
from PIL import Image
from datetime import datetime
sys.path.append(\"..\")
import VisionFive.boardtype as board_t
# from lib import LCD2inch4_lib
from lib import LCD_ST7735_lib
from lib import LCD_GC9306_lib
from lib import LCD_ILI9488_lib
\"\"\"
--------------------------------------------------------------- {
Init
\"\"\"
WHITE = 0xffffff
# WHITE = 0x0000
BLUE = 0xFF0000
lcd_num = 3
# 1 st7735, 2 gc9306, 3 ili9488
pin_res = 7
pin_dc = 11
# 初始化lcd
# Determining cpu Type: 1 means visionfive1; 2 means visionfive 2
vf_t = board_t.boardtype()
print(\"vf_t \",vf_t)
if vf_t == 1:
SPI_DEVICE = \"/dev/spidev0.0\"
elif vf_t == 2:
SPI_DEVICE = \"/dev/spidev1.0\"
else:
print(\"This module can only be run on a VisionFive board!\")
\"\"\"The initialization settings of 2inch and 2.4inch are distinguished\"\"\"
# pin_res, pin_dc
match lcd_num:
case 1:
print(\"lcd st7735\")
disp = LCD_ST7735_lib.LCD_ST7735(7, 11, SPI_DEVICE)
disp.lcd_init_st7735()
case 2:
print(\"lcd gc9306\")
disp = LCD_GC9306_lib.LCD_GC9306(7, 11, SPI_DEVICE)
disp.lcd_init_gc9306()
case 3:
print(\"lcd ili9488\")
disp = LCD_ILI9488_lib.LCD_ILI9488(7, 11, SPI_DEVICE)
disp.lcd_init_ili9488()
case _:
print(\"unknown lcd\")
# 獲取文件夾中圖片名稱
folder_path = \"./picture\"
# folder_path = \"./picture_column\"
# folder_path = \"./tmp\"
items = os.listdir(folder_path)
file_paths = []
for item in items:
item_path = os.path.join(folder_path, item)
if os.path.isfile(item_path) and \"._\" not in item and \".DS_Store\" not in item:
# if os.path.isfile(item_path):# 只保留文件
file_paths.append(item_path)
\"\"\"
} ---------------------------------------------------------------
\"\"\"
def show_img(image_path):
time_start = time.time()
# print(time.time(),\"show img\")
print(image_path)
disp.lcd_ShowImage(image_path, 0, 50)
time_end = time.time()
print(\"cost time:\",time_end-time_start)
# time.sleep(2)
# def show_img(image_path):
#time_start = time.time()
## print(time.time(),\"show img\")
#image = Image.open(image_path)
#disp.lcd_ShowImage(image, 0, 50)
#image.close()
#time_end = time.time()
#print(\"cost time:\",time_end-time_start)
## time.sleep(2)
def test_clear():
# print(\"clear write\")
# time.sleep(2)
print(\"clear screen -- White\")
disp.lcd_clear(WHITE)
time.sleep(2)
print(\"clear screen -- Blue\")
if lcd_num == 3:
# Blue=0x03F0000
# Blue=0xFC0000
# Blue=0x3F0000
Blue=0x03F000
else:
Blue=0x001f
disp.lcd_clear(Blue)
time.sleep(2)
def get_time():
times = time.time()
# print(times)
local_times = time.localtime(times)
local_time_asctimes = time.asctime(local_times)
# print(local_time_asctimes)
return local_time_asctimes
def get_time2():
now = datetime.now()
formatted_time = now.strftime(\"%Y年%m月%d日 %H時(shí)%M分%S秒\")
latinFileName= formatted_time.encode(\"utf-8\").decode(\"latin1\")
return latinFileName
def get_file_list():
file_nummax = 0
# 獲取文件夾中圖片名稱
folder_path = \"./picture\"
# folder_path = \"./picture_column\"
# folder_path = \"./tmp\"
items = os.listdir(folder_path)
file_paths = []
for item in items:
item_path = os.path.join(folder_path, item)
if os.path.isfile(item_path) and \"._\" not in item and \".DS_Store\" not in item:
# if os.path.isfile(item_path):# 只保留文件
file_paths.append(item_path)
file_nummax += 1
print(\"file max\",file_nummax)
return file_paths,file_nummax
def is_12h():
time_hour = datetime.now().hour
if time_hour == 24 & flag_update == True:
print(\"12點(diǎn)了\")
flag_update = False
return True
else:
flag_update = True
print(time_hour)
return False
def is_sec(sec=0):
time_second = datetime.now().second
if time_second % sec == 0 :
return True
# else:
# print(time_second)
return False
def main():
print(\"-----------lcd demo-------------\")
disp.lcd_clear(WHITE)
# test_clear()
# test picture and lcd xy direction
# show_img(\"./tmp/line.jpg\")
# show_img(\"./tmp/line2.jpg\")
# show_img(\"./tmp/line320.jpg\")
# show_img(\"./tmp/line480.jpg\")
# show_img(\"./picture/parrot.bmp\")
# show_img(\"./picture_test/code.jpg\")
# show_img(\"./picture_test/IMG_4512.jpeg\")
# show_img(\"./picture_test/IMG_4529.jpeg\")
# show_img(\"./picture/visionfive2.png\")
# show_img(\"./picture_column/IMG_5415.jpeg\")
print(get_time(),\"show text\")
disp.display_text(get_time())
show_img(\"./picture_column/a.png\")
file_num = 1
(file_list, file_num_max) = get_file_list()
print(file_list[file_num], file_num_max)
show_img(file_list[file_num])
flag_update = False
print(get_time(),\"start\")
while 1:
disp.display_text(get_time())
# print(time.time())
# print(time.time()%5)
if is_sec(10) == True:
if flag_update == True:
file_num += 1
if file_num == file_num_max:
file_num = 0
print(\"\\\\n= \",get_time())
show_img(file_list[file_num])
flag_update = False
else:
flag_update = True
# is_12h()
# if int(time.time()) % 20 == 0 :
#file_num += 1
#show_img(file_list[file_num])
# show_img(\"./picture/IMG_3278.jpeg\")
# disp.lcd_clear_range(WHITE,0,0,0,40)
# for path in file_paths:
#print(time.strftime(\"%Y-%m-%d %H:%M:%S\", time.localtime(time.time())))
#path_tmp = path
#print(path_tmp)
#show_img(path_tmp)
#time.sleep(2)
# except KeyboardInterrupt:
#break
print(\"Exit demo!\")
if __name__ == \'__main__\':
main()
import os
import sys
import time
import logging
import VisionFive.spi as spi
import VisionFive.gpio as gpio
import numpy as np
from PIL import Image, ImageDraw, ImageFont
class LCD_ILI9488:
width = 320
height = 480
rotate = 180
WHITE = 0xffffff
def __init__(self, rst_pin, dc_pin, dev):
gpio.setmode(gpio.BOARD)
self.pin_rst = rst_pin
self.pin_dc = dc_pin
self.pin_bl = 15
self.spidev = dev
spi.getdev(self.spidev)
\"\"\"Reset the maximum clock frequency of communication\"\"\"
\"\"\"The display speed of the picture is positively correlated with the clock frequency\"\"\"
# spi.setmode(500000, 0, 8)
spi.setmode(40000000, 0, 8)
gpio.setup(self.pin_rst, gpio.OUT)
gpio.setup(self.pin_dc, gpio.OUT)
gpio.setup(self.pin_bl, gpio.OUT)
def __del__(self):
spi.freedev()
\"\"\"add a short delay for each change of electrical level\"\"\"
def lcd_reset(self):
gpio.output(self.pin_bl, gpio.HIGH)
# time.sleep(0.120)
# gpio.output(self.pin_rst, gpio.HIGH)
# time.sleep(0.20)
gpio.output(self.pin_rst, gpio.LOW)
time.sleep(0.100)
gpio.output(self.pin_rst, gpio.HIGH)
time.sleep(0.100)
gpio.output(self.pin_bl, gpio.HIGH)
# self.lcd_sendcmd(0x01)
def lcd_spisend(self, data):
spi.transfer(data)
def lcd_sendcmd(self, cmd):
gpio.output(self.pin_dc, gpio.LOW)
spi.transfer(cmd)
def lcd_senddata(self, data):
gpio.output(self.pin_dc, gpio.HIGH)
spi.transfer(data)
\"\"\"write multiple bytes\"\"\"
def lcd_sendnbytes(self, data):
gpio.output(self.pin_dc, gpio.HIGH)
spi.write(data)
\"\"\"common registers\' initialization of 2.4inch LCD module\"\"\"
def lcd_init_ili9488(self):
self.lcd_reset()
# self.lcd_sendcmd(0x11)
# self.lcd_senddata(0x00)
# time.sleep(0.200)
self.lcd_sendcmd(0xE0)
self.lcd_senddata(0x00)
self.lcd_senddata(0x03)
self.lcd_senddata(0x09)
self.lcd_senddata(0x08)
self.lcd_senddata(0x16)
self.lcd_senddata(0x0A)
self.lcd_senddata(0x3F)
self.lcd_senddata(0x78)
self.lcd_senddata(0x4C)
self.lcd_senddata(0x09)
self.lcd_senddata(0x0A)
self.lcd_senddata(0x08)
self.lcd_senddata(0x16)
self.lcd_senddata(0x1A)
self.lcd_senddata(0x0F)
self.lcd_sendcmd(0xE1)
self.lcd_senddata(0x00)
self.lcd_senddata(0x16)
self.lcd_senddata(0x19)
self.lcd_senddata(0x03)
self.lcd_senddata(0x0F)
self.lcd_senddata(0x05)
self.lcd_senddata(0x32)
self.lcd_senddata(0x45)
self.lcd_senddata(0x46)
self.lcd_senddata(0x04)
self.lcd_senddata(0x0E)
self.lcd_senddata(0x0D)
self.lcd_senddata(0x35)
self.lcd_senddata(0x37)
self.lcd_senddata(0x0F)
self.lcd_sendcmd(0xC0)
self.lcd_sendcmd(0x17)
self.lcd_senddata(0x15)
self.lcd_sendcmd(0xC1)
self.lcd_senddata(0x41)
self.lcd_sendcmd(0xC5)
self.lcd_sendcmd(0x00)
self.lcd_senddata(0x12)
self.lcd_senddata(0x80)
self.lcd_sendcmd(0x36)
# self.lcd_sendcmd(0x48)
# self.lcd_sendcmd(0x40)
# self.lcd_sendcmd(0x88)
# self.lcd_sendcmd(0x28)
self.lcd_sendcmd(0x88)
self.lcd_sendcmd(0x3A)
self.lcd_senddata(0x66) # color bit : 0x66 18bit, 0x77 24bit, 0x55 16bit
self.lcd_sendcmd(0xC8)
self.lcd_senddata(0xB1)
self.lcd_sendcmd(0xB0)
self.lcd_sendcmd(0x80)
self.lcd_sendcmd(0xB1)
self.lcd_sendcmd(0x80)
# SDA_EN = 0, DIN and SDO pins are used for 3/4 wire serial interface.
# SDA_EN = 1, DIN/SDA pin is used for 3/4 wire serial interface and SDO pin is not used.
self.lcd_sendcmd(0xB4)
self.lcd_sendcmd(0x02)
self.lcd_sendcmd(0xB6)
self.lcd_sendcmd(0x02)
self.lcd_senddata(0x02)
self.lcd_sendcmd(0xE9)
self.lcd_senddata(0x00)
self.lcd_sendcmd(0x53)
self.lcd_senddata(0x28)
self.lcd_sendcmd(0x51)
self.lcd_senddata(0x7F)
self.lcd_sendcmd(0xF7)
self.lcd_senddata(0xA9)
self.lcd_senddata(0x51)
self.lcd_senddata(0x2C)
self.lcd_senddata(0x02)
self.lcd_sendcmd(0x11)
# self.lcd_senddata(0x00)
time.sleep(0.100)
self.lcd_sendcmd(0x29)
def lcd_set_rotate():
match self.rotate:
case 0:
self.lcd_sendcmd(0x36)
self.lcd_sendcmd(0x88)
case 90:
self.lcd_sendcmd(0x36)
self.lcd_sendcmd(0x28)
case 180:
self.lcd_sendcmd(0x36)
self.lcd_sendcmd(0x48)
case 270:
self.lcd_sendcmd(0x36)
self.lcd_sendcmd(0xE8)
case _:
self.lcd_sendcmd(0x36)
self.lcd_sendcmd(0x88)
def lcd_setPos(self, Xstart, Ystart, Xend, Yend):
self.lcd_sendcmd(0x2A)
self.lcd_senddata(Xstart >> 8)
self.lcd_senddata(Xstart & 0xFF)
self.lcd_senddata((Xend - 1) >> 8)
self.lcd_senddata((Xend - 1) & 0xFF)
self.lcd_sendcmd(0x2B)
self.lcd_senddata(Ystart >> 8)
self.lcd_senddata(Ystart & 0xFF)
self.lcd_senddata((Yend - 1) >> 8)
self.lcd_senddata((Yend - 1) & 0xFF)
self.lcd_sendcmd(0x2C)
def lcd_clear(self, color):
\"\"\"Clear contents of image buffer\"\"\"
_buffer = [color] * (self.width * self.height * 3)# * 3
print(_buffer[0],_buffer[1],_buffer[2])
# self.lcd_setPos(0, 0, self.width, self.height)
self.lcd_setPos(0, 0, self.width, self.height)
gpio.output(self.pin_dc, gpio.HIGH)
\"\"\"modify the original single byte write to multi byte write\"\"\"
# for i in range(0,len(_buffer)):
# self.lcd_spisend(_buffer[i])
self.lcd_sendnbytes(_buffer)
# self.lcd_sendcmd(0x29)
def lcd_clear_range(self, color, x_start, y_start, x_end, y_end):
\"\"\"Clear contents of image buffer\"\"\"
_buffer = [color] * (self.width * self.height * 3)# * 3
print(_buffer[0],_buffer[1],_buffer[2])
# self.lcd_setPos(0, 0, self.width, self.height)
self.lcd_setPos(x_start, y_start, x_end, y_end)
gpio.output(self.pin_dc, gpio.HIGH)
\"\"\"modify the original single byte write to multi byte write\"\"\"
# for i in range(0,len(_buffer)):
# self.lcd_spisend(_buffer[i])
self.lcd_sendnbytes(_buffer)
# self.lcd_sendcmd(0x29)
def Image_to_RGB565(self, Image):
img = np.asarray(Image)
pix = np.zeros((self.width, self.height, 3), dtype=np.uint8)
# RGB888 >> RGB565
pix[..., [0]] = np.add(
np.bitwise_and(img[..., [0]], 0xF8), np.right_shift(img[..., [1]], 5)
)
pix[..., [1]] = np.add(
np.bitwise_and(np.left_shift(img[..., [1]], 3), 0xE0),
np.right_shift(img[..., [2]], 3),
)
pix = pix.flatten().tolist()
# return pix.flatten().tolist()
return pix
def Image_to_RGB666(self, Image):
# 將RGB888轉(zhuǎn)換為RGB666
img = np.asarray(Image)
# 創(chuàng)建一個(gè)(寬度, 高度, 3)的數(shù)組,每個(gè)通道6位,用uint8存儲(chǔ)
pix = np.zeros((self.width, self.height, 3), dtype=np.uint8)
# RGB888 >> RGB666轉(zhuǎn)換
# 每個(gè)通道保留高6位(右移2位丟棄最低2位)
pix[..., 0] = np.right_shift(img[..., 0], 2)# 紅色通道(6位)
pix[..., 1] = np.right_shift(img[..., 1], 2)# 綠色通道(6位)
pix[..., 2] = np.right_shift(img[..., 2], 2)# 藍(lán)色通道(6位)
return pix
def Image_RGB888_to_RGB666(self, Image):
img = np.asarray(Image)
pix = np.zeros((self.height, self.width, 3), dtype=np.uint8)
pix[..., [0]] = np.left_shift(np.left_shift(img[..., [0]], 2), 2)
pix[..., [1]] = np.left_shift(np.left_shift(img[..., [1]], 2), 2)
pix[..., [2]] = np.left_shift(np.left_shift(img[..., [2]], 2), 2)
return pix.flatten().tolist()
def display_text(self, text, font_size=30, x=0, y=10, color=(0,0,0)):
# self.lcd_clear(self.WHITE)
# 創(chuàng)建與屏幕尺寸相同的圖像
font_width = 320
font_height = 50
image = Image.new(\'RGB\', (font_width, font_height), color=(255, 255, 255))# 黑色背景
draw = ImageDraw.Draw(image)
# 加載字體 (使用系統(tǒng)字體或自定義字體文件)
try:
# 嘗試加載系統(tǒng)字體
font = ImageFont.truetype(\'/usr/01_LCD/lib/DejaVuSans.ttf\', font_size)
# print(\"find ttf\")
except IOError:
#fallback到默認(rèn)字體
font = ImageFont.load_default()
# print(\"not find ttf\")
# 在圖像上繪制文字
draw.text((x, y), text, font=font, fill=color)
img_array = np.asarray(image, dtype=np.uint8)# 形狀為 (height, width, 3),值范圍[0,255]
# 創(chuàng)建存儲(chǔ)6位數(shù)據(jù)的數(shù)組
pix = np.zeros((self.height, self.width, 3), dtype=np.uint8)
# 比例縮放:將8位值[0,255]映射到6位值[0,63]
# 公式:6位值 = 8位值 × (63/255),四舍五入取整
scale_factor = 63 * 4 / 255# 縮放因子
pix = np.round(img_array * scale_factor).astype(np.uint8)
pix = pix.flatten().tolist()
self.lcd_sendcmd(0x36)
# self.lcd_senddata(0xC8)
self.lcd_senddata(0x48)
self.lcd_setPos(0, 0, font_width, font_height)
gpio.output(self.pin_dc, gpio.HIGH)
# 顯示圖像到屏幕
# display.display(image)
self.lcd_sendnbytes(pix)
def lcd_ShowImage(self, image_path, Xstart, Ystart):
\"\"\"Set buffer to value of Python Imaging Library Image_show.\"\"\"
\"\"\"Write display buffer to physical display\"\"\"
Image_show = Image.open(image_path)
# print(\"Image_show.mode\", Image_show.mode)
tmp_width, tmp_height = Image_show.size
# print(\"sss\",tmp_width,tmp_height)
if tmp_width > tmp_height:
width_ratio = self.width / tmp_height
height_ratio = self.height / tmp_width
else:
width_ratio = self.width / tmp_width
height_ratio = self.height / tmp_height
scale_ratio = min(width_ratio, height_ratio)
new_width = int(tmp_width * scale_ratio)
new_height = int(tmp_height * scale_ratio)
# print(\"scale_ratio\",tmp_width,tmp_height)
# if tmp_width > tmp_height:
#print(\"change width to height\")
#new_size = (new_height, new_width)
# else:
new_size = (new_width, new_height)
# Image_show = Image_show.resize(new_size, Image_show.Resampling.LANCZOS)
Image_show = Image_show.resize(new_size, 1)
# ValueError: Unknown resampling filter (Image_show.Resampling.NEAREST). Use Image_show.Resampling.NEAREST (0), Image_show.Resampling.LANCZOS (1), Image_show.Resampling.BILINEAR (2), Image_show.Resampling.BICUBIC (3), Image_show.Resampling.BOX (4) or Image_show.Resampling.HAMMING (5)
# print(\"new_size\",new_size)
imwidth, imheight = Image_show.size
# print(\"Image_show: width = \", imwidth, \", height = \", imheight)
if Image_show.mode == \"RGBA\":
Image_show = Image_show.convert(\"RGB\")
# if imwidth == self.height and imheight == self.width:
if imwidth > imheight:
img_array = np.asarray(Image_show, dtype=np.uint8)# 形狀為 (height, width, 3),值范圍[0,255]
# 創(chuàng)建存儲(chǔ)6位數(shù)據(jù)的數(shù)組
pix = np.zeros((self.width, self.height, 3), dtype=np.uint8)
# 比例縮放:將8位值[0,255]映射到6位值[0,63]
# 公式:6位值 = 8位值 × (63/255),四舍五入取整
scale_factor = 63 * 4 / 255# 縮放因子
pix = np.round(img_array * scale_factor).astype(np.uint8)
pix = pix.flatten().tolist()
self.lcd_sendcmd(
0x36
)# define read/write scanning direction of frame memory
self.lcd_senddata(0x28)
math_x = imwidth+Ystart
# if math_x < self.height:
#print(\"picture is oversize.\")
self.lcd_setPos(Ystart, 0, math_x, self.width)
# self.lcd_setPos(Ystart, 0, imwidth+Ystart, imheight)
# self.lcd_setPos(0, 0, self.height, self.width)
gpio.output(self.pin_dc, gpio.HIGH)
\"\"\"modify the original single byte write to multi byte write\"\"\"
# for i in range(0,len(pix),1):
#self.lcd_spisend(pix[i])
self.lcd_sendnbytes(pix)
else:
print(\"same direction\")
img_array = np.asarray(Image_show, dtype=np.uint8)# 形狀為 (height, width, 3),值范圍[0,255]
# 創(chuàng)建存儲(chǔ)6位數(shù)據(jù)的數(shù)組
pix = np.zeros((self.height, self.width, 3), dtype=np.uint8)
# 比例縮放:將8位值[0,255]映射到6位值[0,63]
# 公式:6位值 = 8位值 × (63/255),四舍五入取整
scale_factor = 63 * 4 / 255# 縮放因子
pix = np.round(img_array * scale_factor).astype(np.uint8)
pix = pix.flatten().tolist()
self.lcd_sendcmd(0x36)
# self.lcd_senddata(0xC8)
self.lcd_senddata(0x48)
self.lcd_setPos(0, Ystart, self.width, self.height)
gpio.output(self.pin_dc, gpio.HIGH)
\"\"\"modify the original single byte write to multi byte write\"\"\"
# for i in range(0,len(pix)):
# self.lcd_spisend(pix[i])
self.lcd_sendnbytes(pix)
Image_show.close()
# def lcd_ShowImage(self, Image, Xstart, Ystart):
#\"\"\"Set buffer to value of Python Imaging Library image.\"\"\"
#\"\"\"Write display buffer to physical display\"\"\"
## print(\"image.mode\", Image.mode)
#tmp_width, tmp_height = Image.size
## print(\"sss\",tmp_width,tmp_height)
#if tmp_width > tmp_height:
#width_ratio = self.width / tmp_height
#height_ratio = self.height / tmp_width
#else:
#width_ratio = self.width / tmp_width
#height_ratio = self.height / tmp_height
#scale_ratio = min(width_ratio, height_ratio)
#new_width = int(tmp_width * scale_ratio)
#new_height = int(tmp_height * scale_ratio)
## print(\"scale_ratio\",tmp_width,tmp_height)
## if tmp_width > tmp_height:
##print(\"change width to height\")
##new_size = (new_height, new_width)
## else:
#new_size = (new_width, new_height)
## Image = Image.resize(new_size, Image.Resampling.LANCZOS)
#Image = Image.resize(new_size, 1)
## ValueError: Unknown resampling filter (Image.Resampling.NEAREST). Use Image.Resampling.NEAREST (0), Image.Resampling.LANCZOS (1), Image.Resampling.BILINEAR (2), Image.Resampling.BICUBIC (3), Image.Resampling.BOX (4) or Image.Resampling.HAMMING (5)
## print(\"new_size\",new_size)
#imwidth, imheight = Image.size
## print(\"image: width = \", imwidth, \", height = \", imheight)
#if Image.mode == \"RGBA\":
#Image = Image.convert(\"RGB\")
## if imwidth == self.height and imheight == self.width:
#if imwidth > imheight:
#img_array = np.asarray(Image, dtype=np.uint8)# 形狀為 (height, width, 3),值范圍[0,255]
## 創(chuàng)建存儲(chǔ)6位數(shù)據(jù)的數(shù)組
#pix = np.zeros((self.width, self.height, 3), dtype=np.uint8)
## 比例縮放:將8位值[0,255]映射到6位值[0,63]
## 公式:6位值 = 8位值 × (63/255),四舍五入取整
#scale_factor = 63 * 4 / 255# 縮放因子
#pix = np.round(img_array * scale_factor).astype(np.uint8)
#pix = pix.flatten().tolist()
#self.lcd_sendcmd(
# 0x36
#)# define read/write scanning direction of frame memory
#self.lcd_senddata(0x28)
#math_x = imwidth+Ystart
## if math_x < self.height:
##print(\"picture is oversize.\")
#self.lcd_setPos(Ystart, 0, math_x, self.width)
## self.lcd_setPos(Ystart, 0, imwidth+Ystart, imheight)
## self.lcd_setPos(0, 0, self.height, self.width)
#gpio.output(self.pin_dc, gpio.HIGH)
#\"\"\"modify the original single byte write to multi byte write\"\"\"
## for i in range(0,len(pix),1):
##self.lcd_spisend(pix[i])
#self.lcd_sendnbytes(pix)
#else:
#print(\"same direction\")
#img_array = np.asarray(Image, dtype=np.uint8)# 形狀為 (height, width, 3),值范圍[0,255]
## 創(chuàng)建存儲(chǔ)6位數(shù)據(jù)的數(shù)組
#pix = np.zeros((self.height, self.width, 3), dtype=np.uint8)
## 比例縮放:將8位值[0,255]映射到6位值[0,63]
## 公式:6位值 = 8位值 × (63/255),四舍五入取整
#scale_factor = 63 * 4 / 255# 縮放因子
#pix = np.round(img_array * scale_factor).astype(np.uint8)
#pix = pix.flatten().tolist()
#self.lcd_sendcmd(0x36)
## self.lcd_senddata(0xC8)
#self.lcd_senddata(0x48)
#self.lcd_setPos(0, Ystart, self.width, self.height)
#gpio.output(self.pin_dc, gpio.HIGH)
#\"\"\"modify the original single byte write to multi byte write\"\"\"
## for i in range(0,len(pix)):
## self.lcd_spisend(pix[i])
#self.lcd_sendnbytes(pix)
# def lcd_ShowImage(self, Image, Xstart, Ystart):
#\"\"\"Set buffer to value of Python Imaging Library image.\"\"\"
#\"\"\"Write display buffer to physical display\"\"\"
#print(\"image.mode\", Image.mode)
#tmp_width, tmp_height = Image.size
#print(\"sss\",tmp_width,tmp_height)
#if tmp_width > tmp_height:
#print(\"change width to height\")
#new_size = (self.height, self.width)
#else:
#new_size = (self.width, self.height-Ystart)
#Image = Image.resize(new_size)
#print(\"new_size\",new_size)
#imwidth, imheight = Image.size
#print(\"image: width = \", imwidth, \", height = \", imheight)
#if Image.mode == \"RGBA\":
#Image = Image.convert(\"RGB\")
#if imwidth == self.height and imheight == self.width:
#img_array = np.asarray(Image, dtype=np.uint8)# 形狀為 (height, width, 3),值范圍[0,255]
## 創(chuàng)建存儲(chǔ)6位數(shù)據(jù)的數(shù)組
#pix = np.zeros((self.width, self.height, 3), dtype=np.uint8)
## 比例縮放:將8位值[0,255]映射到6位值[0,63]
## 公式:6位值 = 8位值 × (63/255),四舍五入取整
#scale_factor = 63 * 4 / 255# 縮放因子
#pix = np.round(img_array * scale_factor).astype(np.uint8)
#pix = pix.flatten().tolist()
#self.lcd_sendcmd(
# 0x36
#)# define read/write scanning direction of frame memory
#self.lcd_senddata(0x28)
#self.lcd_setPos(0, 0, self.height, self.width)
#gpio.output(self.pin_dc, gpio.HIGH)
#\"\"\"modify the original single byte write to multi byte write\"\"\"
## for i in range(0,len(pix),1):
##self.lcd_spisend(pix[i])
#self.lcd_sendnbytes(pix)
#else:
#print(\"same direction\")
## self.lcd_clear_range(self.WHITE,0,0,0,Ystart)
#img_array = np.asarray(Image, dtype=np.uint8)# 形狀為 (height, width, 3),值范圍[0,255]
## 創(chuàng)建存儲(chǔ)6位數(shù)據(jù)的數(shù)組
#pix = np.zeros((self.height, self.width, 3), dtype=np.uint8)
## 比例縮放:將8位值[0,255]映射到6位值[0,63]
## 公式:6位值 = 8位值 × (63/255),四舍五入取整
#scale_factor = 63 * 4 / 255# 縮放因子
#pix = np.round(img_array * scale_factor).astype(np.uint8)
#pix = pix.flatten().tolist()
#self.lcd_sendcmd(0x36)
## self.lcd_senddata(0xC8)
#self.lcd_senddata(0x48)
#self.lcd_setPos(0, Ystart, self.width, self.height)
#gpio.output(self.pin_dc, gpio.HIGH)
#\"\"\"modify the original single byte write to multi byte write\"\"\"
## for i in range(0,len(pix)):
## self.lcd_spisend(pix[i])
#self.lcd_sendnbytes(pix)
2025-08-12 23:56:27
讓我們?cè)跇?shù)莓派單板計(jì)算機(jī)上解鎖生物識(shí)別控制功能吧!生物識(shí)別技術(shù)利用每個(gè)人獨(dú)有的、不易復(fù)制的生理或行為特征進(jìn)行身份驗(yàn)證。地球上每個(gè)人的指紋都是獨(dú)一無(wú)二的,讓我們一起來(lái)探索指紋的奇妙用途吧!本文將介紹
2025-08-09 13:14:11
722 
一、引言
賽昉科技提供了許多參考性文檔,其中不乏使用昉·星光 2測(cè)試在AI圖像處理的應(yīng)用場(chǎng)景。上期咱分享了二維碼檢測(cè)與解碼效果,只要攝像頭采集圖像夠清晰,掃描二維碼與解析效率還是挺好的。今兒來(lái)分享一下,基于上期環(huán)境,再對(duì)攝像頭應(yīng)用進(jìn)行展開(kāi),評(píng)估其在人臉識(shí)別、物體識(shí)別以及圖像邊緣檢測(cè)上的應(yīng)用。
二、人臉識(shí)別
(1)硬件搭建
準(zhǔn)備一本封面印有人臉頭像的雜志,以便后續(xù)測(cè)試檢測(cè)效果。
固定uvc攝像機(jī),然后調(diào)好焦距,使其圖像采集清晰。
(2)代碼實(shí)現(xiàn)
與上期的二維碼檢測(cè)實(shí)驗(yàn)一樣,基于OpenCV模型去實(shí)現(xiàn)人臉圖像檢測(cè)、輪廓標(biāo)注、置信度和識(shí)別。在人臉圖像檢測(cè)的同時(shí),顯示檢測(cè)的置信度,置信度小于50%過(guò)濾掉。,因此需用到深度學(xué)習(xí)的檢測(cè)模型,github上有提供開(kāi)源的OpenCV DNN或FaceNet模型,可滿足置信度顯示需求。準(zhǔn)備預(yù)訓(xùn)練模型文件
通過(guò)github上獲取“deploy.prototxt.txt”與“res10_300x300_ssd_iter_140000.caffemodel”文件。*附件:deploy.prototxt.zip*附件:res10_300x300_ssd_iter_140000.zip
編寫(xiě)“face_detection.py”源代碼,內(nèi)容如下:
import cv2
import numpy as np
net = cv2.dnn.readNetFromCaffe(\"deploy.prototxt.txt\", \"res10_300x300_ssd_iter_140000.caffemodel\")
cap = cv2.VideoCapture(4, cv2.CAP_V4L2)
while True:
ret, frame = cap.read()
if not ret:
break
(h, w) = frame.shape[:2]
blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 1.0,
(300, 300), (104.0, 177.0, 123.0))
net.setInput(blob)
detections = net.forward()
for i in range(detections.shape[2]):
confidence = detections[0, 0, i, 2]
if confidence < 0.5:
continue
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype(\"int\")
cv2.rectangle(frame, (startX, startY), (endX, endY), (0, 255, 0), 2)
text = f\"Face: {confidence * 100:.2f}%\"
cv2.putText(frame, text, (startX, startY - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
cv2.imshow(\"Face Detection with Confidence\", frame)
key = cv2.waitKey(1) & 0xFF
# if the `q` key was pressed, break from the loop
if key == ord(\"q\"):
break
cap.release()
cv2.destroyAllWindows()
將編寫(xiě)好的“face_detection.py”源文件與上述下載好的預(yù)訓(xùn)練模型文件放在同一文件夾下。
桌面方式登錄后,然后終端中進(jìn)到該文件夾下,普通用戶身份執(zhí)行“ python3 face_detection.py”,呈現(xiàn)的檢測(cè)效果見(jiàn)底部視頻。
三、物體識(shí)別
因?yàn)橹暗亩S碼檢測(cè)功能基本已實(shí)現(xiàn),因此環(huán)境這塊,相應(yīng)的依賴軟件包都已安裝好了,這里調(diào)用YOLO-V3模型進(jìn)行通用物體的識(shí)別。
基于yolo-v3模型的應(yīng)用“object_detection.cpp”源代碼如下:
#include <fstream>
#include <sstream>
#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#if defined(CV_CXX11) && defined(HAVE_THREADS)
#define USE_THREADS 1
#endif
#ifdef USE_THREADS
#include <mutex>
#include <thread>
#include <queue>
#endif
#include \"common.hpp\"
std::string keys =
\"{ helph| | Print help message. }\"
\"{ @Alias| | An alias name of model to extract preprocessing parameters from models.yml file. }\"
\"{ zoo| models.yml | An optional path to file with preprocessing parameters }\"
\"{ device|0 | camera device number. }\"
\"{ input i| | Path to input image or video file. Skip this argument to capture frames from a camera. }\"
\"{ framework f | | Optional name of an origin framework of the model. Detect it automatically if it does not set. }\"
\"{ classes| | Optional path to a text file with names of classes to label detected objects. }\"
\"{ thr| .5 | Confidence threshold. }\"
\"{ nms| .4 | Non-maximum suppression threshold. }\"
\"{ backend|0 | Choose one of computation backends: \"
\"0: automatically (by default), \"
\"1: Halide language (http://halide-lang.org/), \"
\"2: Intel\'s Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), \"
\"3: OpenCV implementation, \"
\"4: VKCOM, \"
\"5: CUDA }\"
\"{ target| 0 | Choose one of target computation devices: \"
\"0: CPU target (by default), \"
\"1: OpenCL, \"
\"2: OpenCL fp16 (half-float precision), \"
\"3: VPU, \"
\"4: Vulkan, \"
\"6: CUDA, \"
\"7: CUDA fp16 (half-float preprocess) }\"
\"{ async | 0 | Number of asynchronous forwards at the same time. \"
\"Choose 0 for synchronous mode }\";
using namespace cv;
using namespace dnn;
float confThreshold, nmsThreshold;
std::vector<std::string> classes;
inline void preprocess(const Mat& frame, Net& net, Size inpSize, float scale,
const Scalar& mean, bool swapRB);
void postprocess(Mat& frame, const std::vector<Mat>& out, Net& net, int backend);
void drawPred(int classId, float conf, int left, int top, int right, int bottom, Mat& frame);
void callback(int pos, void* userdata);
#ifdef USE_THREADS
template <typename T>
class QueueFPS : public std::queue<T>
{
public:
QueueFPS() : counter(0) {}
void push(const T& entry)
{
std::lock_guard<std::mutex> lock(mutex);
std::queue<T>::push(entry);
counter += 1;
if (counter == 1)
{
// Start counting from a second frame (warmup).
tm.reset();
tm.start();
}
}
T get()
{
std::lock_guard<std::mutex> lock(mutex);
T entry = this->front();
this->pop();
return entry;
}
float getFPS()
{
tm.stop();
double fps = counter / tm.getTimeSec();
tm.start();
return static_cast<float>(fps);
}
void clear()
{
std::lock_guard<std::mutex> lock(mutex);
while (!this->empty())
this->pop();
}
unsigned int counter;
private:
TickMeter tm;
std::mutex mutex;
};
#endif// USE_THREADS
int main(int argc, char** argv)
{
CommandLineParser parser(argc, argv, keys);
const std::string modelName = parser.get<String>(\"@alias\");
const std::string zooFile = parser.get<String>(\"zoo\");
keys += genPreprocArguments(modelName, zooFile);
parser = CommandLineParser(argc, argv, keys);
parser.about(\"Use this script to run object detection deep learning networks using OpenCV.\");
if (argc == 1 || parser.has(\"help\"))
{
parser.printMessage();
return 0;
}
confThreshold = parser.get<float>(\"thr\");
nmsThreshold = parser.get<float>(\"nms\");
float scale = parser.get<float>(\"scale\");
Scalar mean = parser.get<Scalar>(\"mean\");
bool swapRB = parser.get<bool>(\"rgb\");
int inpWidth = parser.get<int>(\"width\");
int inpHeight = parser.get<int>(\"height\");
size_t asyncNumReq = parser.get<int>(\"async\");
CV_Assert(parser.has(\"model\"));
std::string modelPath = findFile(parser.get<String>(\"model\"));
std::string configPath = findFile(parser.get<String>(\"config\"));
// Open file with classes names.
if (parser.has(\"classes\"))
{
std::string file = parser.get<String>(\"classes\");
std::ifstream ifs(file.c_str());
if (!ifs.is_open())
CV_Error(Error::StsError, \"File \" + file + \" not found\");
std::string line;
while (std::getline(ifs, line))
{
classes.push_back(line);
}
}
// Load a model.
Net net = readNet(modelPath, configPath, parser.get<String>(\"framework\"));
int backend = parser.get<int>(\"backend\");
net.setPreferableBackend(backend);
net.setPreferableTarget(parser.get<int>(\"target\"));
std::vector<String> outNames = net.getUnconnectedOutLayersNames();
// Create a window
static const std::string kWinName = \"Deep learning object detection in OpenCV\";
namedWindow(kWinName, WINDOW_NORMAL);
int initialConf = (int)(confThreshold * 100);
createTrackbar(\"Confidence threshold, %\", kWinName, &initialConf, 99, callback);
// Open a video file or an image file or a camera stream.
VideoCapture cap;
if (parser.has(\"input\"))
cap.open(parser.get<String>(\"input\"));
else
cap.open(parser.get<int>(\"device\"));
#ifdef USE_THREADS
bool process = true;
// Frames capturing thread
QueueFPS<Mat> framesQueue;
std::thread framesThread([&](){
Mat frame;
while (process)
{
cap >> frame;
if (!frame.empty())
framesQueue.push(frame.clone());
else
break;
}
});
// Frames processing thread
QueueFPS<Mat> processedFramesQueue;
QueueFPS<std::vector<Mat> > predictionsQueue;
std::thread processingThread([&](){
std::queue<AsyncArray> futureOutputs;
Mat blob;
while (process)
{
// Get a next frame
Mat frame;
{
if (!framesQueue.empty())
{
frame = framesQueue.get();
if (asyncNumReq)
{
if (futureOutputs.size() == asyncNumReq)
frame = Mat();
}
else
framesQueue.clear();// Skip the rest of frames
}
}
// Process the frame
if (!frame.empty())
{
preprocess(frame, net, Size(inpWidth, inpHeight), scale, mean, swapRB);
processedFramesQueue.push(frame);
if (asyncNumReq)
{
futureOutputs.push(net.forwardAsync());
}
else
{
std::vector<Mat> outs;
net.forward(outs, outNames);
predictionsQueue.push(outs);
}
}
while (!futureOutputs.empty() &&
futureOutputs.front().wait_for(std::chrono::seconds(0)))
{
AsyncArray async_out = futureOutputs.front();
futureOutputs.pop();
Mat out;
async_out.get(out);
predictionsQueue.push({out});
}
}
});
// Postprocessing and rendering loop
while (waitKey(1) < 0)
{
if (predictionsQueue.empty())
continue;
std::vector<Mat> outs = predictionsQueue.get();
Mat frame = processedFramesQueue.get();
postprocess(frame, outs, net, backend);
if (predictionsQueue.counter > 1)
{
std::string label = format(\"Camera: %.2f FPS\", framesQueue.getFPS());
putText(frame, label, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0));
label = format(\"Network: %.2f FPS\", predictionsQueue.getFPS());
putText(frame, label, Point(0, 30), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0));
label = format(\"Skipped frames: %d\", framesQueue.counter - predictionsQueue.counter);
putText(frame, label, Point(0, 45), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0));
}
imshow(kWinName, frame);
}
process = false;
framesThread.join();
processingThread.join();
#else// USE_THREADS
if (asyncNumReq)
CV_Error(Error::StsNotImplemented, \"Asynchronous forward is supported only with Inference Engine backend.\");
// Process frames.
Mat frame, blob;
while (waitKey(1) < 0)
{
cap >> frame;
if (frame.empty())
{
waitKey();
break;
}
preprocess(frame, net, Size(inpWidth, inpHeight), scale, mean, swapRB);
std::vector<Mat> outs;
net.forward(outs, outNames);
postprocess(frame, outs, net, backend);
// Put efficiency information.
std::vector<double> layersTimes;
double freq = getTickFrequency() / 1000;
double t = net.getPerfProfile(layersTimes) / freq;
std::string label = format(\"Inference time: %.2f ms\", t);
putText(frame, label, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0));
imshow(kWinName, frame);
}
#endif// USE_THREADS
return 0;
}
inline void preprocess(const Mat& frame, Net& net, Size inpSize, float scale,
const Scalar& mean, bool swapRB)
{
static Mat blob;
// Create a 4D blob from a frame.
if (inpSize.width <= 0) inpSize.width = frame.cols;
if (inpSize.height <= 0) inpSize.height = frame.rows;
blobFromImage(frame, blob, 1.0, inpSize, Scalar(), swapRB, false, CV_8U);
// Run a model.
net.setInput(blob, \"\", scale, mean);
if (net.getLayer(0)->outputNameToIndex(\"im_info\") != -1)// Faster-RCNN or R-FCN
{
resize(frame, frame, inpSize);
Mat imInfo = (Mat_<float>(1, 3) << inpSize.height, inpSize.width, 1.6f);
net.setInput(imInfo, \"im_info\");
}
}
void postprocess(Mat& frame, const std::vector<Mat>& outs, Net& net, int backend)
{
static std::vector<int> outLayers = net.getUnconnectedOutLayers();
static std::string outLayerType = net.getLayer(outLayers[0])->type;
std::vector<int> classIds;
std::vector<float> confidences;
std::vector<Rect> boxes;
if (outLayerType == \"DetectionOutput\")
{
// Network produces output blob with a shape 1x1xNx7 where N is a number of
// detections and an every detection is a vector of values
// [batchId, classId, confidence, left, top, right, bottom]
CV_Assert(outs.size() > 0);
for (size_t k = 0; k < outs.size(); k++)
{
float* data = (float*)outs[k].data;
for (size_t i = 0; i < outs[k].total(); i += 7)
{
float confidence = data[i + 2];
if (confidence > confThreshold)
{
int left= (int)data[i + 3];
int top = (int)data[i + 4];
int right= (int)data[i + 5];
int bottom = (int)data[i + 6];
int width= right - left + 1;
int height = bottom - top + 1;
if (width <= 2 || height <= 2)
{
left= (int)(data[i + 3] * frame.cols);
top = (int)(data[i + 4] * frame.rows);
right= (int)(data[i + 5] * frame.cols);
bottom = (int)(data[i + 6] * frame.rows);
width= right - left + 1;
height = bottom - top + 1;
}
classIds.push_back((int)(data[i + 1]) - 1);// Skip 0th background class id.
boxes.push_back(Rect(left, top, width, height));
confidences.push_back(confidence);
}
}
}
}
else if (outLayerType == \"Region\")
{
for (size_t i = 0; i < outs.size(); ++i)
{
// Network produces output blob with a shape NxC where N is a number of
// detected objects and C is a number of classes + 4 where the first 4
// numbers are [center_x, center_y, width, height]
float* data = (float*)outs.data;
for (int j = 0; j < outs.rows; ++j, data += outs.cols)
{
Mat scores = outs.row(j).colRange(5, outs.cols);
Point classIdPoint;
double confidence;
minMaxLoc(scores, 0, &confidence, 0, &classIdPoint);
if (confidence > confThreshold)
{
int centerX = (int)(data[0] * frame.cols);
int centerY = (int)(data[1] * frame.rows);
int width = (int)(data[2] * frame.cols);
int height = (int)(data[3] * frame.rows);
int left = centerX - width / 2;
int top = centerY - height / 2;
classIds.push_back(classIdPoint.x);
confidences.push_back((float)confidence);
boxes.push_back(Rect(left, top, width, height));
}
}
}
}
else
CV_Error(Error::StsNotImplemented, \"Unknown output layer type: \" + outLayerType);
// NMS is used inside Region layer only on DNN_BACKEND_OPENCV for another backends we need NMS in sample
// or NMS is required if number of outputs > 1
if (outLayers.size() > 1 || (outLayerType == \"Region\" && backend != DNN_BACKEND_OPENCV))
{
std::map<int, std::vector<size_t> > class2indices;
for (size_t i = 0; i < classIds.size(); i++)
{
if (confidences >= confThreshold)
{
class2indices[classIds].push_back(i);
}
}
std::vector<Rect> nmsBoxes;
std::vector<float> nmsConfidences;
std::vector<int> nmsClassIds;
for (std::map<int, std::vector<size_t> >::iterator it = class2indices.begin(); it != class2indices.end(); ++it)
{
std::vector<Rect> localBoxes;
std::vector<float> localConfidences;
std::vector<size_t> classIndices = it->second;
for (size_t i = 0; i < classIndices.size(); i++)
{
localBoxes.push_back(boxes[classIndices]);
localConfidences.push_back(confidences[classIndices]);
}
std::vector<int> nmsIndices;
NMSBoxes(localBoxes, localConfidences, confThreshold, nmsThreshold, nmsIndices);
for (size_t i = 0; i < nmsIndices.size(); i++)
{
size_t idx = nmsIndices;
nmsBoxes.push_back(localBoxes[idx]);
nmsConfidences.push_back(localConfidences[idx]);
nmsClassIds.push_back(it->first);
}
}
boxes = nmsBoxes;
classIds = nmsClassIds;
confidences = nmsConfidences;
}
for (size_t idx = 0; idx < boxes.size(); ++idx)
{
Rect box = boxes[idx];
drawPred(classIds[idx], confidences[idx], box.x, box.y,
box.x + box.width, box.y + box.height, frame);
}
}
void drawPred(int classId, float conf, int left, int top, int right, int bottom, Mat& frame)
{
rectangle(frame, Point(left, top), Point(right, bottom), Scalar(0, 255, 0));
std::string label = format(\"%.2f\", conf);
if (!classes.empty())
{
CV_Assert(classId < (int)classes.size());
label = classes[classId] + \": \" + label;
}
int baseLine;
Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
top = max(top, labelSize.height);
rectangle(frame, Point(left, top - labelSize.height),
Point(left + labelSize.width, top + baseLine), Scalar::all(255), FILLED);
putText(frame, label, Point(left, top), FONT_HERSHEY_SIMPLEX, 0.5, Scalar());
}
void callback(int pos, void*)
{
confThreshold = pos * 0.01f;
}
桌面方式登錄后,終端中user身份直接運(yùn)行“v4l2-ctl --list-device”指令,確認(rèn)USB攝像機(jī)的ID號(hào)。然后再運(yùn)行“example_dnn_object_detection --config=/usr/share/opencv4/yolo-v3/yolov3-tiny.cfg --model=/usr/share/opencv4/yolo-v3/yolov3-tiny.weights --classes=/usr/share/opencv4/yolo-v3/classes.txt --width=416--height=416--scale=0.00392--rgb --target=1--device=4”
四、圖像邊緣檢測(cè)
這里調(diào)用OpenCV官方提供的“edge.py”源文件,內(nèi)容如下:
#!/usr/bin/env python
\'\'\'
This sample demonstrates Canny edge detection.
Usage:
edge.py [<video source>]
Trackbars control edge thresholds.
\'\'\'
# Python 2/3 compatibility
from __future__ import print_function
import cv2 as cv
import numpy as np
# relative module
import video
# built-in module
import sys
def main():
try:
fn = sys.argv[1]
cam = int(fn)
except:
fn = 0
def nothing(*arg):
pass
cv.namedWindow(\'edge\', 0)
cv.resizeWindow(\'edge\', 640, 480)
cv.createTrackbar(\'thrs1\', \'edge\', 2000, 5000, nothing)
cv.createTrackbar(\'thrs2\', \'edge\', 4000, 5000, nothing)
cap = cv.VideoCapture(cam, cv.CAP_V4L2)
if cam == 1:
cap.set(cv.CAP_PROP_CONVERT_RGB, 0)
while True:
if cam == 1:
ret, img_origin = cap.read()
img = cv.cvtColor(img_origin, cv.COLOR_YUV2BGR_NV12)
else:
ret, img = cap.read()
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
thrs1 = cv.getTrackbarPos(\'thrs1\', \'edge\')
thrs2 = cv.getTrackbarPos(\'thrs2\', \'edge\')
edge = cv.Canny(gray, thrs1, thrs2, apertureSize=5)
vis = img.copy()
vis = np.uint8(vis/2.)
vis[edge != 0] = (0, 255, 0)
cv.imshow(\'edge\', vis)
ch = cv.waitKey(5)
if ch == 27:
break
print(\'Done\')
if __name__ == \'__main__\':
print(__doc__)
main()
cv.destroyAllWindows()
同樣的,桌面方式登錄后,終端中user身份直接運(yùn)行“v4l2-ctl --list-device”指令,確認(rèn)USB攝像機(jī)的ID號(hào)。然后再運(yùn)行:
cd /usr/share/doc/opencv-doc/examples/python/
python3 edge.py 4
默認(rèn)參數(shù)下運(yùn)行效果如下:
調(diào)節(jié)thrs1、thrs2參數(shù)后,檢測(cè)的圖像邊緣區(qū)分更明顯。
五、小結(jié)
綜上評(píng)測(cè)效果,昉·星光2連接一個(gè)通用的USB攝像機(jī),即可高效實(shí)現(xiàn)基于OpenCV的人臉檢測(cè)識(shí)別、通用物體識(shí)別、二維碼檢測(cè)與解析,圖像邊緣檢測(cè)等功能,證實(shí)該開(kāi)發(fā)板可以運(yùn)用在AI智能終端產(chǎn)品設(shè)計(jì)上,賽昉科技也提供了諸多指導(dǎo)性文檔,一個(gè)應(yīng)用可通過(guò)多種模型來(lái)實(shí)現(xiàn),有提供C++源代碼方式的接口,也有python源代碼。提供的參考例程很有代表性,足見(jiàn)該開(kāi)發(fā)板應(yīng)用的場(chǎng)景廣泛,尤其是在邊緣AI設(shè)計(jì)中,具有很好的市場(chǎng)競(jìng)爭(zhēng)力。
2025-08-07 00:49:09
一、引言
上期借助官方提供的VisionFive.gpio包,實(shí)現(xiàn)了LED點(diǎn)陣屏內(nèi)容的完善。這期來(lái)分享一下,使用VisionFive 2開(kāi)發(fā)板連接通用的USB攝像機(jī),抓拍二維碼,并完成對(duì)二維碼的內(nèi)容進(jìn)行解碼。
二、搭建環(huán)境
使用PuTTY的ssh接口連接后開(kāi)發(fā)板后,需要執(zhí)行以下指令,以完成 StarFive Packages及其依賴的必要組件安裝,下載安裝時(shí)長(zhǎng)比較久。
https://github.com/starfive-tech/Debian/releases/download/v0.8.0-engineering-release-wayland/install_package_and_dependencies.sh
chmod +x install_package_and_dependencies.sh
sudo ./install_package_and_dependencies.sh
前段時(shí)間燒錄的系統(tǒng)是使用閃迪16GB的TF卡,在執(zhí)行完腳本后,報(bào)安裝vlc的libixml10與libupnp13組件下載安裝失敗,這可能跟網(wǎng)絡(luò)狀態(tài)、TF讀寫(xiě)速度相關(guān)。
于是乎,筆者換了一張32GB的TF,重新燒寫(xiě)了202409版系統(tǒng)鏡像,重新安裝了vim、python3-pip、VisionFive.gpio包等?;谇捌趫?zhí)行腳本的情況,在Linux中在線下載安裝必備的組件包比較費(fèi)時(shí)費(fèi)勁,因此根據(jù)“install_package_and_dependencies.sh”腳本中的內(nèi)容,將要下載的數(shù)據(jù)包,通過(guò)windows下的瀏覽器去下載,這樣就高效多了。下載好的文件列表信息如下:
將windows中下載好的組件包文件,通過(guò)FileZilla的ssh接口,傳輸給VisionFive 2,保存到user目錄下。然后在腳本中再對(duì)內(nèi)容進(jìn)行修改,以免執(zhí)行指令時(shí),按照腳本再去指定網(wǎng)址下下載。由于TF空間夠大,為避免后續(xù)麻煩,因此將刪除數(shù)據(jù)包的指令屏蔽掉。
#!/bin/sh
#LibreOffice Runtime Dependencies
DEBIAN_FRONTEND=noninteractive apt-get install libxslt1.1 openjdk-11-jdk -y
#QT Runtime Dependencies
DEBIAN_FRONTEND=noninteractive apt-get install libmd4c-dev libdouble-conversion-dev libc6-dev libpcre2-16-0 \"^libxcb.*\" libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-x11-dev -y
#Firefox Runtime Dependencies
DEBIAN_FRONTEND=noninteractive apt-get install libevent-dev libdbus-glib-1-dev -y
#FFMPEG Runtime Dependencies
DEBIAN_FRONTEND=noninteractive apt-get install libopenal-dev libcdio-paranoia-dev libdc1394-dev libcaca-dev libv4l-dev libpocketsphinx-dev libbs2b-dev liblilv-0-0 librubberband-dev libmysofa-dev libflite1 libass-dev libvidstab-dev libzmq3-dev libzimg-dev libgme-dev libopenmpt-dev libchromaprint-dev librabbitmq-dev libssh-dev libsrt-openssl-devliba52-0.7.4-dev libhwy1 libjxl0.7 -y
#v4l2test Runtime Dependencies
DEBIAN_FRONTEND=noninteractive apt-get install libv4l-0 libv4l-dev v4l-utils libjpeg-dev libdrm-dev -y
#chromium Runtime Dependencies
DEBIAN_FRONTEND=noninteractive apt-get install libre2-9 libminizip-dev -y
#opencv Runtime Dependencies
DEBIAN_FRONTEND=noninteractive apt-get install fonts-mathjax libjs-mathjax libpython3.11-minimal libpython3.11-stdlib python3-numpy python3.11 python3.11-minimal python3-h5py libvtk9.1 libqt5test5 libqt5opengl5 libtesseract5 libgdcm-dev libgdal-dev -y
#cogl/cultter Runtime Dependencies
DEBIAN_FRONTEND=noninteractive apt-get install gstreamer1.0-clutter-3.0 -y
#vlc Runtime Dependencies
DEBIAN_FRONTEND=noninteractive apt-get install fonts-freefont-ttf libaribb24-0 libcddb2 libdvbpsi10 libebml5 libixml10 liblirc-client0 liblua5.2-0 libmad0 libmatroska7 libprotobuf-lite32 libqt5x11extras5 libresid-builder0c2a libsdl-image1.2 libsdl1.2debian libsidplay2 libspatialaudio0 libupnp13 libva-wayland2 libvncclient1 -y
#wget https://github.com/starfive-tech/Debian/releases/download/v0.8.0-engineering-release-wayland/firefox_105.0_202305_riscv64.deb
#wget https://github.com/starfive-tech/Debian/releases/download/v0.8.0-engineering-release-wayland/libreoffice_7.5_riscv64.deb
#wget https://github.com/starfive-tech/Debian/releases/download/v0.8.0-engineering-release-wayland/nodejs-18.0.0_riscv64.deb
#wget https://github.com/starfive-tech/Debian/releases/download/v0.8.0-engineering-release-wayland/nwjs_0.65.1-2_riscv64.deb
#wget https://github.com/starfive-tech/Debian/releases/download/v0.8.0-engineering-release-wayland/qt-5.15-2-wayland_riscv64.deb
#wget https://github.com/starfive-tech/Debian/releases/download/v0.8.0-engineering-release-wayland/v4l2test_riscv64.deb
#wget https://github.com/starfive-tech/Debian/releases/download/v0.8.0-engineering-release-wayland/v8-10.2.154.13_riscv64.deb
#wget https://github.com/starfive-tech/Debian/releases/download/v0.8.0-engineering-release-wayland/chromium-103.0.5060.114.deb
dpkg -i nodejs-18.0.0_riscv64.deb
dpkg -i v8-10.2.154.13_riscv64.deb
dpkg -i libreoffice_7.5_riscv64.deb
dpkg -i qt-5.15-2-wayland_riscv64.deb
dpkg -i firefox_105.0_202305_riscv64.deb
dpkg -i nwjs_0.65.1-2_riscv64.deb
dpkg -i v4l2test_riscv64.deb
dpkg -i chromium-103.0.5060.114.deb
#rm nodejs-18.0.0_riscv64.deb
#rm v8-10.2.154.13_riscv64.deb
#rm libreoffice_7.5_riscv64.deb
#rm qt-5.15-2-wayland_riscv64.deb
#rm firefox_105.0_202305_riscv64.deb
#rm nwjs_0.65.1-2_riscv64.deb
#rm v4l2test_riscv64.deb
#rm chromium-103.0.5060.114.deb
##### ffmpeg install ######
#wget https://github.com/starfive-tech/Debian/releases/download/v0.8.0-engineering-release-wayland/multimedia.tar.gz
tar -xvzf multimedia.tar.gz
cd $PWD/multimedia
dpkg --force-all -i *.deb
cd ..
#### opencv install #####
#wget https://github.com/starfive-tech/Debian/releases/download/v0.8.0-engineering-release-wayland/opencv-deb.tar.gz
tar -xvzf opencv-deb.tar.gz
cd $PWD/opencv-deb
dpkg --force-all -i *.deb
cd ..
#### cogl/clutter install #####
#wget https://github.com/starfive-tech/Debian/releases/download/v0.8.0-engineering-release-wayland/gst-cogl.tar.gz
tar -xvzf gst-cogl.tar.gz
cd $PWD/gst-cogl
dpkg --force-all -i *.deb
cd ..
### vlc-package install
#wget https://github.com/starfive-tech/Debian/releases/download/v0.8.0-engineering-release-wayland/vlc-packages.tar.gz
tar -xvzf vlc-packages.tar.gz
cd $PWD/vlc-packages
dpkg --force-all -i *.deb
cd ..
#rm -rf multimedia.tar.gz
#rm -rf opencv-deb.tar.gz
#rm -rf gst-cogl.tar.gz
#rm -rf vlc-packages.tar.gz
#rm -rf multimedia
#rm -rf opencv-deb
#rm -rf gst-cogl
#rm -rf vlc-packages
echo \"Install Success\"
這樣處理后,再執(zhí)行腳本就高效了,在線安裝必備的依賴庫(kù)文件后,直接本地解壓并安裝組件包。
三、USB攝像頭
本次實(shí)驗(yàn)采用的是一個(gè)分辨率為2592*1944的uvc免驅(qū)工業(yè)攝像機(jī)。無(wú)自動(dòng)聚焦功能,由于之前貼了濾光片,因此手動(dòng)對(duì)焦,以及周?chē)h(huán)境給光顯得尤為重要。攝像頭配無(wú)畸變鏡頭,實(shí)物如下:
攝像頭需要在windows下使用“AMCap”工具,手機(jī)支架固定好位置,調(diào)好焦距,使采集的圖片清晰明朗。
四、安裝USB軟件包
由于此次使用的USB攝像頭,并沒(méi)用到IMX219 CSI攝像頭,因此需要安裝關(guān)于USB的軟件包。
sudo apt-get install usbutils
在user目錄下執(zhí)行上述指令,然后通過(guò)lsusb指令,可查詢到接入U(xiǎn)SB接口的攝像頭。
使用“v4l2-ctl --list-device”可查詢當(dāng)前掛載video設(shè)備
使用“v4l2-ctl --device=/dev/video4 --all”可查看掛載在video4的USB攝像頭配置信息
五、執(zhí)行實(shí)驗(yàn)代碼
cd /usr/share/doc/opencv-doc/examples/python/
python3 qrcode.py --device=4
通過(guò)執(zhí)行上述兩步指令后,可啟動(dòng)二維碼檢測(cè)程序。然而執(zhí)行后提示如下:
針對(duì)上述問(wèn)題,需要安裝好opencv的python依賴軟件包
sudo apt-get install libopencv-dev python3-opencv
成功安裝完成后,在ssh終端再次執(zhí)行“python3 qrcode.py --device=4”指令,提示如下:
出現(xiàn)上述情況,需通過(guò)HDMI的桌面方式登錄后,在系統(tǒng)終端中,進(jìn)入到“/usr/share/doc/opencv-doc/examples/python/”路徑下,再執(zhí)行“qrcode.py”腳本程序。
攝像頭聚焦良好,可以順利檢測(cè)到二維碼并解析成功。
終端打印如下:
六、后記
正如上述,可以成功檢測(cè)二維碼并解析成功,但是次日,想錄制視頻發(fā)帖時(shí),結(jié)果發(fā)現(xiàn)桌面方式無(wú)法登錄了,不管是user身份還是root身份,密碼也沒(méi)改,怎么回事?使用Uart或者ssh方式,都可以正常連接登錄。徹底懵了,因?yàn)榇罱ㄟ@個(gè)環(huán)境聯(lián)網(wǎng)比較費(fèi)時(shí)。
“Not listed?”也不知道是啥原因,聯(lián)系賽昉FAE遠(yuǎn)程協(xié)助,也沒(méi)查出bug所在,想通過(guò)拷貝TF鏡像來(lái)分析問(wèn)題,但是插入TF卡彈出三個(gè)盤(pán),且三個(gè)盤(pán)都強(qiáng)制要求格式化才能訪問(wèn),這樣的話也沒(méi)法通過(guò)Ubuntu虛擬機(jī)來(lái)掛載TF,使用dd命令將鏡像壓縮出來(lái)了。無(wú)奈只能重刷系統(tǒng),重新構(gòu)建環(huán)境了。
經(jīng)過(guò)再次聯(lián)網(wǎng)下載必備軟件包后,運(yùn)行指令后,桌面終端提示:
這說(shuō)明攝像頭檢測(cè)到二維碼并解析出結(jié)果了,但是由于不是以u(píng)ser身份運(yùn)行指令,所以無(wú)法打開(kāi)firefox瀏覽器,“python3 qrcode.py --device=4”命令需要以u(píng)ser身份運(yùn)行,不用加sudo執(zhí)行,這樣就能順利啟動(dòng)firefox,視頻見(jiàn)底部。
后面正常關(guān)機(jī)后,再次通過(guò)HDMI桌面的方式登錄系統(tǒng),可以正常登錄,沒(méi)有復(fù)現(xiàn)到之前的情況。初步結(jié)論:
①、可能是由于多重身份運(yùn)行后,導(dǎo)致文件丟失。當(dāng)時(shí)使用ssh以root身份執(zhí)行shutdown關(guān)機(jī)指令,而在桌面的終端以u(píng)ser身份運(yùn)行著二維碼檢測(cè)程序。
②、攝像頭掛載的device設(shè)備號(hào)不固定,非法訪問(wèn)到其它系統(tǒng)媒體設(shè)備號(hào)了,導(dǎo)致gdm3驅(qū)動(dòng)異常。
好了,此次實(shí)驗(yàn)分享到此結(jié)束,以上經(jīng)歷僅供參考,遇到類(lèi)似問(wèn)題的壇友,歡迎留言共同討論。
2025-07-30 01:01:39
工業(yè)計(jì)算機(jī)對(duì)某些行業(yè)至關(guān)重要。我們將在下面詳細(xì)解釋這些行業(yè)中的工業(yè)計(jì)算機(jī)應(yīng)用。1.制造與工業(yè)自動(dòng)化工業(yè)級(jí)計(jì)算機(jī)非常適合制造工廠,特別是那些想要自動(dòng)化裝配過(guò)程的工廠。在這樣的環(huán)境中,工業(yè)計(jì)算機(jī)可用
2025-07-28 16:07:15
442 
拿到VisionFive 2板子有段時(shí)間了,之前也寫(xiě)過(guò)幾篇帖子了,今天來(lái)寫(xiě)一下刷寫(xiě)Ubuntu系統(tǒng)。
1。首先從ubunut官網(wǎng)下載VisionFive 2的固件,塞防已經(jīng)做好了適配。
https://canonical-ubutu-boards.readthedocs-hosted.com/en/latst/how-to/starfive-visionfive-2/
2。下載下來(lái)后,解壓出來(lái)
使用上面的固件,
3。打開(kāi)燒錄軟件
選擇固件
選擇磁盤(pán)
燒錄開(kāi)始
等5分鐘燒錄完畢
還要驗(yàn)證一遍
最后燒錄完畢
鏈接好板子和串口
打開(kāi)putty
可以看到燒錄正常,進(jìn)入U(xiǎn)buntu了
2025-07-23 13:17:27
一、引言
上期咱分享了環(huán)境搭建與GPIO點(diǎn)燈實(shí)驗(yàn),今兒在此基礎(chǔ)上,驗(yàn)證一下驅(qū)動(dòng)8x8的LED點(diǎn)陣屏,由于之前的環(huán)境與VisionFive.gpio包已安裝好,因此實(shí)驗(yàn)起來(lái)比較順利。由參考的腳本可知,實(shí)驗(yàn)中需用到一個(gè)按鍵開(kāi)關(guān)作為中斷觸發(fā)LED點(diǎn)陣屏顯示。
二、硬件連接
上圖為硬件實(shí)物連接情況,初始上電狀態(tài)為全亮LED點(diǎn)陣屏。
咱連接點(diǎn)陣屏與按鍵模塊,是通過(guò)連接板上40-Pin Header。
MAX7219串行點(diǎn)陣顯示模塊與板上40-Pin Header連接關(guān)系:
按鍵開(kāi)關(guān)一端連接一個(gè)信號(hào)輸入GPIO口,設(shè)定為低電平有效;另一端連接GND。
三、腳本修改
在官方提供的參考腳本上,擴(kuò)展顯示其它內(nèi)容。
命令執(zhí)行流程:
開(kāi)發(fā)板上電后,串口輸出顯示待登錄狀態(tài),說(shuō)明網(wǎng)絡(luò)已初始化完成,因此可使用PuTTY登錄到開(kāi)發(fā)板上。然后將普通用戶變更為超級(jí)用戶,然后進(jìn)入到sample-code目錄下,由于官方提供的參考腳本文件為只讀屬性,因此使用vim編輯是無(wú)效的,需要使用chmod命令將文件屬性更新為可讀可寫(xiě)。這樣接下來(lái)可以使用vim編輯該腳本文件。命令執(zhí)行步驟如下圖所示:
edge_detection_with_LED_Matrix.py代碼完善如下:
\"\"\"
Step 1:
Please make sure the LED Dot Matrix is connected to the correct pins.
The following table describes how to connect LED Dot Matrix to the 40-pin header.
-----------------------------------------
___MAX7219_______Pin Number_____Pin Name
VCC 25V Power
GND 34GND
DIN 40 GPIO44
CS38 GPIO61
CLK 36 GPIO36
Step 2:
Please make sure the button is connected to the correct pins.
The following table describes how to connect the button to the 40-pin header.
----------------------------------------
_______button____Pin Number_____Pin Name
one end 37 GPIO60
The other end39GND
-----------------------------------------
\"\"\"
import VisionFive.gpio as GPIO
import sys
import time
DIN = 40
CS = 38
CLK = 36
# Display logo data.
buffer = [
\"01111000\",
\"01000000\",
\"01111000\",
\"01001111\",
\"01111001\",
\"00001111\",
\"00000001\",
\"00001111\",
]
#Display arabic numeral 13.
buffer_13 = [
\"00001000\",
\"00001000\",
\"01111111\",
\"01001001\",
\"01001001\",
\"01111111\",
\"00001000\",
\"00001000\",
]
#Display arabic numeral 12.
buffer_12 = [
\"11111111\",
\"10111101\",
\"10010001\",
\"10111101\",
\"10010101\",
\"10111101\",
\"10000001\",
\"11111111\",
]
#Display arabic numeral 11.
buffer_11 = [
\"01111110\",
\"00100000\",
\"00100000\",
\"00111110\",
\"01000010\",
\"10000100\",
\"00010100\",
\"00001000\",
]
#Display arabic numeral 10.
buffer_10 = [
\"01001001\",
\"01111111\",
\"00001000\",
\"00011111\",
\"00100010\",
\"01011010\",
\"00000100\",
\"00001000\",
]
#Display arabic numeral 9.
buffer_9 = [
\"00111110\",
\"00100010\",
\"00100010\",
\"00111110\",
\"00000010\",
\"00000010\",
\"00000010\",
\"00111110\",
]
#Display arabic numeral 8.
buffer_8 = [
\"00111110\",
\"00100010\",
\"00100010\",
\"00111110\",
\"00100010\",
\"00100010\",
\"00100010\",
\"00111110\",
]
#Display arabic numeral 7.
buffer_7 = [
\"00111110\",
\"00000010\",
\"00000010\",
\"00000100\",
\"00000100\",
\"00000100\",
\"00001000\",
\"00001000\",
]
#Display arabic numeral 6.
buffer_6 = [
\"00111110\",
\"00100000\",
\"00100000\",
\"00111110\",
\"00100010\",
\"00100010\",
\"00100010\",
\"00111110\",
]
#Display arabic numeral 5.
buffer_5 = [
\"00011110\",
\"00010000\",
\"00010000\",
\"00011110\",
\"00000010\",
\"00000010\",
\"00000010\",
\"00011110\",
]
# Display arabic numeral 4.
buffer_4 = [
\"00000100\",
\"00001000\",
\"00010000\",
\"00100100\",
\"01000100\",
\"01111111\",
\"00000100\",
\"00000100\",
]
# Display arabic numeral 3.
buffer_3 = [
\"00011100\",
\"00100010\",
\"00000010\",
\"00011110\",
\"00000010\",
\"00100010\",
\"00011100\",
\"00000000\",
]
# Display arabic numeral 2.
buffer_2 = [
\"00011100\",
\"00100010\",
\"00000010\",
\"00000100\",
\"00001000\",
\"00010000\",
\"00111110\",
\"00000000\",
]
# Display arabic numeral 1.
buffer_1 = [
\"00001000\",
\"00011000\",
\"00001000\",
\"00001000\",
\"00001000\",
\"00001000\",
\"00001000\",
\"00011100\",
]
# LED turn off data.
buffer_off = [\"0\", \"0\", \"0\", \"0\", \"0\", \"0\", \"0\", \"0\"]
key_pin = 37
def sendbyte(bytedata):
for bit in range(0, 8):
if (bytedata << bit) & 0x80:
GPIO.output(DIN, GPIO.HIGH)
else:
GPIO.output(DIN, GPIO.LOW)
# Configure the voltage level of CLK as high.
GPIO.output(CLK, GPIO.HIGH)
# Configure the voltage level of CLK as low.
GPIO.output(CLK, GPIO.LOW)
def WriteToReg(regaddr, bytedata):
GPIO.output(CS, GPIO.HIGH)
GPIO.output(CS, GPIO.LOW)
GPIO.output(CLK, GPIO.LOW)
sendbyte(regaddr)
sendbyte(bytedata)
GPIO.output(CS, GPIO.HIGH)
def disp_clean():
time.sleep(0.1)
for i in range(0, 8):
# Write data to register address. Finally the LED matrix displays StarFive logo.
WriteToReg(i + 1, int(buffer_off[i], 2))
time.sleep(1)
def disp_numeral_13_to_1():
for id in range(13, 0, -1):
buffer_name = \"buffer_{}\".format(id)
list_buffer = eval(buffer_name)
for j in range(0, 8):
# Write data to the register address. Finally the LED matrix displays with numeral from 5 to 1.
WriteToReg(j + 1, int(list_buffer[j], 2))
time.sleep(1)
for j in range(0, 8):
# Write data to the register address. Finally turn off the LED matrix.
WriteToReg(j + 1, int(buffer_off[j], 2))
time.sleep(0.1)
def flash_logo():
for loop in range(0, 5):
for j in range(0, 8):
# Write data to the register address. Finally turn off the LED matrix.
WriteToReg(j + 1, int(buffer_off[j], 2))
time.sleep(0.1)
for j in range(0, 8):
# Write data to the register address. Finally the LED matrix displays with StarFive logo.
WriteToReg(j + 1, int(buffer[j], 2))
time.sleep(0.1)
def WriteALLReg():
# Clean screen
disp_clean()
# Display numeral from 5 to 1
disp_numeral_13_to_1()
# Flash starfive logo.
flash_logo()
def initData():
WriteToReg(0x09, 0x00)# Set the decode mode.
WriteToReg(0x0A, 0x03)# Set the brightness.
WriteToReg(0x0B, 0x07)# Set the scan limitation.
WriteToReg(0x0C, 0x01)# Set the power mode.
WriteToReg(0x0F, 0x00)
# the callback function for edge detection
def detect(pin, edge_type):
if edge_type == 1:
et = \"Rising\"
else:
et = \"Falling\"
if GPIO.getmode() == GPIO.BOARD:
print(\"{} edge was detected on pin:{}\".format(et, pin))
else:
print(\"{} edge was detected on GPIO:{}\".format(et, pin))
WriteALLReg()
global flag
flag = 1
def main():
global flag
flag = 0
# Set the gpio mode as \'BOARD\'.
GPIO.setmode(GPIO.BOARD)
# Configure the direction of DIN, CS, and CLK as output.
GPIO.setup(DIN, GPIO.OUT)
GPIO.setup(CS, GPIO.OUT)
GPIO.setup(CLK, GPIO.OUT)
# Configure the direction of key_pin as input.
GPIO.setup(key_pin, GPIO.IN)
# Both edge rising and falling can be detected, also set bouncetime(unit: millisecond) to avoid jitter
GPIO.add_event_detect(key_pin, GPIO.FALLING, callback=detect, bouncetime=2)
initData()
print(\"*------------------------------------------------------*\")
print(\"Please press the key on pin {} to launch !!!\".format(key_pin))
while True:
if flag == 1:
disp_clean()
GPIO.cleanup()
break
print(\"Exit demo.\")
if __name__ == \"__main__\":
sys.exit(main())
當(dāng)然開(kāi)發(fā)者也可以使用FileZilla拷貝工具,通過(guò)ssh來(lái)傳遞python腳本文件,但沒(méi)有vim來(lái)的高效。
使用vim編寫(xiě)完,保存退出后,運(yùn)行“python3 edge_detection_with_LED_Matrix.py”命令即可驗(yàn)證效果。
四、顯示效果
開(kāi)機(jī)后,第一次運(yùn)行腳本程序,如頂部視頻所示,由全屏點(diǎn)亮,通過(guò)按一下開(kāi)關(guān),觸發(fā)點(diǎn)陣屏顯示。顯示內(nèi)容有“中國(guó)萬(wàn)歲”,“9”~“1”數(shù)字倒計(jì)顯示,接著閃爍顯示賽防科技的logo后熄滅點(diǎn)陣屏。再次運(yùn)行腳本程序,如底部視頻所示,按鍵后可再次觸發(fā)。
五、終端命令關(guān)機(jī)
昉·星光 2開(kāi)機(jī)后,說(shuō)實(shí)話CPU處的溫度還是有點(diǎn)高的,用手指觸碰感覺(jué)很燙手,后期會(huì)考慮添上一個(gè)16mm x 16mm的散熱片。在終端中,root模式下運(yùn)行shutdown指令,在沒(méi)有連接串口調(diào)試工具前提下,可做到完全關(guān)斷電源,體驗(yàn)不錯(cuò)。
2025-07-23 00:45:41
的里程碑
VisionFive 2憑借JH7110四核處理器 + Vulkan GPU突破了RISC-V平臺(tái)游戲性能瓶頸。實(shí)測(cè)證明:
?性價(jià)比突出 :單板成本<800元,性能持平樹(shù)莓派4B游戲方案
?生態(tài)
2025-07-22 20:58:22
測(cè)試板卡上聲卡,播放mp3音樂(lè)。
一、聲卡設(shè)備
1.1、查詢板卡的聲卡設(shè)備
板卡支持兩個(gè)聲卡,一個(gè)是自身聲卡設(shè)備,一個(gè)是HDMI聲卡。
user@starfive:~$ sudo aplay -l
1.2、查看系統(tǒng)默認(rèn)的聲卡
默認(rèn)的聲卡設(shè)備不是上面的兩個(gè)聲卡
1.3、修改默認(rèn)的聲卡設(shè)備
修改聲卡配置文件user@starfive:~$ sudo vi /etc/asound.conf
添加內(nèi)容
pcm.!default {
type hw
card 0
}
ctl.!default {
type hw
card 0
}
重啟設(shè)備后,查看默認(rèn)聲卡為修改的設(shè)備
1.4、測(cè)試設(shè)備
二、安裝播放器軟件user@starfive:~$ sudo apt-get install sox libsox-fmt-all
三、播放音樂(lè)
播放復(fù)制到板卡上的音樂(lè)
user@starfive:~$ sudo play bzyy.mp3
2025-07-22 07:33:58
讓我們討論一下部署堅(jiān)固的自動(dòng)化計(jì)算機(jī)的一些好處。1.溫度范圍寬自動(dòng)化計(jì)算機(jī)經(jīng)過(guò)工程設(shè)計(jì),配備了支持寬溫度范圍的組件,使自動(dòng)化計(jì)算解決方案能夠在各種不同的極端環(huán)境中運(yùn)行。自動(dòng)化計(jì)算機(jī)能夠在溫度達(dá)到
2025-07-21 16:44:20
498 
ARM一樣,自己搭建環(huán)境自己編譯吧。
今天第一篇,主要分享下怎么搭建riscv編譯環(huán)境環(huán)境,用無(wú)線網(wǎng)卡鏈接wifi也需要編譯內(nèi)核,磨刀不誤砍柴工嘛。
下面主要介紹RISC-V架構(gòu)下GNU工具鏈
2025-07-20 23:59:40
一、概況
昉·星光 2是全球首款集成了GPU的高性能RISC-V單板計(jì)算機(jī)。與昉·星光相比,昉·星光 2全面升級(jí),在處理器速度、多媒體處理能力、可擴(kuò)展性等方面均有顯著提升。性能卓越,價(jià)格親民,昉
2025-07-20 22:55:46
。ED-SBC3300系列是一款基于RaspberryPiCM5的Mini-ITX工業(yè)單板計(jì)算機(jī)主板。根據(jù)不同的應(yīng)用場(chǎng)景和用戶需求,可選擇不同規(guī)格的RAM和eMMC
2025-07-20 20:34:18
883 
1、ollama平臺(tái)搭建
ollama可以快速地部署開(kāi)源大模型,網(wǎng)址為https://ollama.com, 試用該平臺(tái),可以在多平臺(tái)上部署 Deepseek-R1, Qwen3, Llama, Gemma等開(kāi)源大模型。當(dāng)然,一些閉源的(類(lèi)似chatgpt, gemini)是不支持部署的。如下圖:
在端側(cè)部署大模型,個(gè)人認(rèn)為最大的好處:是可以避免因文本或圖片上傳而造成的信息泄露,因?yàn)橐磺形谋据斎牒屯评矶伎梢噪x線進(jìn)行。
我們進(jìn)到其github,發(fā)現(xiàn)其并沒(méi)有提供risc-v架構(gòu)的編譯產(chǎn)物。
所以,我們需要下載源碼來(lái)編譯ollama。
Git clone https://github.com/ollama/ollama.git
需要先安裝一下編譯需要的庫(kù):
sudo apt install g++ build-essential cmake
解壓ollama源碼之后,按照ollama github里的build from source指導(dǎo),進(jìn)行編譯,編譯步驟如下圖所示:
在調(diào)用go run . serve發(fā)現(xiàn)抱錯(cuò):go指令不存在,這是因?yàn)閂isionFive2板卡沒(méi)有安裝go,下面我們來(lái)安裝一下go
2、go安裝
進(jìn)到go的官網(wǎng)https://go.dev/dl/,按照慣例,我們要找一下是否有risc-v的編譯產(chǎn)物,如果沒(méi)有的話,又得源碼編譯了。 不過(guò),好在我們發(fā)現(xiàn)了已經(jīng)有release的risc-v的編譯產(chǎn)物了,如下圖,把紅框內(nèi)的文件下載到visionfive2的板卡上。
解壓文件,看到在go/bin/路徑下,有一個(gè)go的可執(zhí)行文件。
我們要把這個(gè)go可執(zhí)行文件添加到環(huán)境變量,具體做法是:在~/.bashrc文件最后添加下圖所示的內(nèi)容
然后
source ~/.bashrc
執(zhí)行
go version
檢查一下,go是否能夠正常運(yùn)行。這里可以看到go的版本,以及編譯的系統(tǒng)和芯片架構(gòu)。
3、拉取/運(yùn)行大語(yǔ)言模型
ollama的使用方法和docker很像。
返回到ollama的編譯路徑,找到ollama可執(zhí)行文件
執(zhí)行
./ollama run qwen3:0.6b
可以看到有個(gè)進(jìn)度條在拉取0.6B的Qwen模型。當(dāng)然也可以拉去deepseek的模型,如下:
./ollama run deepseek-r1:1.5b
可以選擇不同的參數(shù)量版本,參數(shù)量越大,對(duì)算力的要求越高,模型表現(xiàn)越好。
我這里就使用最小的Qwen0.5b來(lái)試一下:
拉取完畢之后,就可以在命令行輸入你想問(wèn)的問(wèn)題:
我讓它幫我寫(xiě)一首詩(shī),指定了主題和要表現(xiàn)的內(nèi)容:
qwen0.6b的表現(xiàn):這個(gè)參數(shù)量的表現(xiàn)只能說(shuō)一般?!奥?tīng)蛙飛”,青蛙怎么會(huì)飛呢。
visionfive2的表現(xiàn):
執(zhí)行
./ollama ps
可以看到當(dāng)前正在運(yùn)行的大模型,以及運(yùn)行方式:CPU。 如果有顯卡的話,這里會(huì)顯示GPU。Visionfive2的gpu應(yīng)該是不支持推理的,所以這里用的是CPU。實(shí)測(cè)下來(lái),運(yùn)行0.6B的模型,自回歸的速度大概是每2秒一個(gè)漢字。
2025-07-19 15:45:24
無(wú)所不在。得益于其強(qiáng)大的硬件和多功能性,樹(shù)莓派被應(yīng)用于各個(gè)行業(yè)。繼續(xù)閱讀,了解這款單板計(jì)算機(jī)如何應(yīng)對(duì)全球挑戰(zhàn),來(lái)讓我們驚嘆。1.學(xué)生將樹(shù)莓派送上太空讓我們從最嚴(yán)苛的
2025-07-16 16:51:01
1170 
官網(wǎng)看到開(kāi)發(fā)板可以安裝測(cè)試openplc,下面來(lái)體驗(yàn)下openplc功能。
一、安裝軟件
1.1、安裝軟件包
root@starfive:~# sudo apt-get install -y curl git udev libxml2-dev autoconf automake autotools-dev icu-devtools libicu-dev libsigsegv2 m4 autoconf-archive gnu-standards libtool gettext m4 make cmake build-essential pkg-config bison flex libtool nodejs libbz2-dev sqlite3 libgdbm-dev openssl libexpat1-dev python${version}-dev python3 libxslt-dev libmodbus5 python3-venv libasio-dev
1.2、下載openplc軟件包
下載地址:https://debian.starfivetech.com/
網(wǎng)盤(pán)路徑:VisionFive2/Engineering Release/202409/debian-packs/openplc.zip
1.3、安裝軟件
下載安裝包復(fù)制到開(kāi)發(fā)板/home/user下,并解壓
user@starfive:~$ unzip openplc.zip
user@starfive:~$ cd openplc
user@starfive:~/openplc$ sudo dpkg -i openplc-vf2.deb
1.4、創(chuàng)建環(huán)境
創(chuàng)建python虛擬環(huán)境并安裝python包
user@starfive:~$ cd openplc_v3/
user@starfive:~/openplc_v3$ sudo python3 -m venv .venv
user@starfive:~/openplc_v3$ sudo .venv/bin/python3 -m pip install requests wget bs4 flask==2.3.3 werkzeug==2.3.7 flask-login==0.6.2 pyserial pymodbus==2.5.3
user@starfive:~/openplc_v3$ sudo .venv/bin/python3 -m pip install VisionFive.gpio-1.3.3-cp311-cp311-linux_riscv64.whl
需要準(zhǔn)備文件VisionFive.gpio-1.3.3-cp311-cp311-linux_riscv64.whl
文件地址:https://pypi.org/project/VisionFive.gpio/1.3.3/
二、測(cè)試
2.1、下載及安裝openplc編輯軟件
軟件下載地址:https://autonomylogic.com/download/
這里我下載windows版本測(cè)試,下載完成后,正常流程安裝軟件。
2.2、創(chuàng)建工程
2.2.1、創(chuàng)建梯形圖工程
2.2.2、測(cè)試梯形圖
2.2.3、生成st文件
2.3、打開(kāi)OpenPLC HMI
瀏覽器輸入板卡的IP:8080http://192.168.1.200:8080/login
輸入用戶名和密碼:openplc,接入HMI界面
進(jìn)入界面后,上傳上步生成的.st文件
重新命令程序名稱
上傳程序后,編譯出現(xiàn)錯(cuò)誤
2025-07-15 23:30:57
工業(yè)自動(dòng)化是指利用自動(dòng)化計(jì)算機(jī)來(lái)控制工業(yè)環(huán)境中的流程、機(jī)器人和機(jī)械,以制造產(chǎn)品或其部件。工業(yè)自動(dòng)化的目的是提高生產(chǎn)率、增加靈活性,并提升制造過(guò)程的質(zhì)量。工業(yè)自動(dòng)化在汽車(chē)制造中體現(xiàn)得最為明顯,其中許多
2025-07-15 16:32:14
602 
一、更新軟件包
編譯之前需要更新所需要的軟件包
hui@hui-virtual-machine:~$ sudo apt-get update
hui@hui-virtual-machine:~$ sudo apt-get upgrade
hui@hui-virtual-machine:~$ sudo apt-get install build-essential automake libtool texinfo bison flex gawk g++ git xxd curl wget gdisk gperf cpio bc screen texinfo unzip libgmp-dev libmpfr-dev libmpc-dev libssl-dev libncurses-dev libglib2.0-dev libpixman-1-dev libyaml-dev patchutils python3-pip zlib1g-dev device-tree-compiler dosfstools mtools kpartx rsync
hui@hui-virtual-machine:~$ curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
hui@hui-virtual-machine:~$ sudo apt-get install git-lfs
二、下載SDK源碼
hui@hui-virtual-machine:~$ git clone https://github.com/starfive-tech/VisionFive2.git
hui@hui-virtual-machine:~$ cd VisionFive2/
hui@hui-virtual-machine:~/VisionFive2$ git checkout --track origin/JH7110_VisionFive2_devel
hui@hui-virtual-machine:~/VisionFive2$ git submodule update --init --recursive
hui@hui-virtual-machine:~/VisionFive2$ cd buildroot && git checkout --track origin/JH7110_VisionFive2_devel && cd ..
hui@hui-virtual-machine:~/VisionFive2$ cd linux && git branch JH7110_VisionFive2_devel origin/JH7110_Vision
hui@hui-virtual-machine:~/VisionFive2$ cd u-boot && git checkout --track origin/JH7110_VisionFive2_devel && cd ..
hui@hui-virtual-machine:~/VisionFive2$ cd opensbi && git checkout --track origin/JH7110_VisionFive2_devel && cd ..
hui@hui-virtual-machine:~/VisionFive2$ cd soft_3rdpart && git checkout JH7110_VisionFive2_devel && cd ..
三、構(gòu)建指令
3.1、構(gòu)建Buildroot、U-Boot、Linux內(nèi)核和BusyBox
hui@hui-virtual-machine:~/VisionFive2$ make -j$(nproc)
編譯完成
編譯后生成的文件
3.2、生成TF卡鏡像
hui@hui-virtual-machine:~/VisionFive2$ make buildroot_rootfs -j$(nproc)
hui@hui-virtual-machine:~/VisionFive2$ make img
編譯完成后,生成的鏡像文件
3.3、燒寫(xiě)系統(tǒng)到TF卡
執(zhí)行下面命令,燒寫(xiě)系統(tǒng)到TF卡
hui@hui-virtual-machine:~/VisionFive2$ sudo dd if=work/sdcard.img of=/dev/sdc bs=4096
四、編譯過(guò)程中遇到的錯(cuò)誤
解決辦法:
修改目錄/VisionFive2/buildroot/package/mesa3d/mesa3d.mk
修改下載連接地址:
hui@hui-virtual-machine:~/VisionFive2/buildroot/package/mesa3d$ sudo vi mesa3d.mk
五、系統(tǒng)運(yùn)行
將燒寫(xiě)的系統(tǒng)的TF卡插入板卡,上電啟動(dòng)。
2025-07-14 00:27:15
單板計(jì)算機(jī),搭載昉·驚鴻-7110(型號(hào):JH-7110)RISC-V應(yīng)用處理器,擁有極強(qiáng)的計(jì)算能力和圖形處理能力。開(kāi)源的昉·星光 2具有強(qiáng)大的軟件適配性,官方適配Debian操作系統(tǒng),同時(shí)通過(guò)社區(qū)合作適配
2025-07-13 20:41:46
拿到賽昉科技的VisionFive 2開(kāi)發(fā)板有段時(shí)間了,之前移植出差調(diào)試設(shè)備,任務(wù)比較繁忙,剛好現(xiàn)在周末有時(shí)間,就來(lái)寫(xiě)下測(cè)評(píng)帖子。
這是板子的包裝,非常的高大上
下面是插電接入網(wǎng)線后的板子實(shí)物圖
運(yùn)行這塊板子,需要自備一個(gè)容量>32G以上的SD卡,否則無(wú)法運(yùn)行debian系統(tǒng)。
為此,我專(zhuān)門(mén)在淘寶上買(mǎi)了一個(gè)64G的SD卡。
首先為了使VisionFive 2板子運(yùn)行起來(lái),先要對(duì)SD進(jìn)行OS燒錄,
這個(gè)非常像給PC臺(tái)式機(jī)安裝操作系統(tǒng),只不過(guò)現(xiàn)在是給VisionFive 2安裝debian linux系統(tǒng)了,然后哪個(gè)SD卡就充當(dāng)固態(tài)硬盤(pán),安裝了系統(tǒng)。
1。先燒錄debian系統(tǒng)到SD卡
https://canonical-ubuntu-boards.readthedocs-hosted.com/en/latest/how-to/starfive-visionfive-2/
根據(jù)這個(gè)網(wǎng)盤(pán)地址下載燒錄固件,然后解壓得到下面的東西
打開(kāi)balenaEtcher軟件
加載這個(gè)固件燒錄到SD中
上面是燒錄,然后還有驗(yàn)證
強(qiáng)烈建議使用有USB3.0接口的電腦進(jìn)行燒錄,我的筆記本只有USB2.0,燒錄一下5分鐘。好慢
燒錄完成后會(huì)顯示上面的圖像
然后將SD卡插入板子的卡槽
使用串口putty連接
輸入用戶名 root
密碼 starfive
進(jìn)入debian系統(tǒng)
輸入lscpu指令查看
4核risv CPU
安裝溫度sensor
apt install lm-sensors
輸入sensors查看板子溫度
顯示是51.5度,有點(diǎn)發(fā)燙
2。進(jìn)行coremark跑分
先從github上下載coremark源碼git clone https://github.com/eembc/coremark.git
使用上面的命令
然后cd coremark切換到coremark文件夾
運(yùn)行make編譯代碼
然后輸入
./coremark.exe
執(zhí)行文件
可以看出最后coremark跑分為5041.477611分,很強(qiáng)的分?jǐn)?shù)了,完爆所有STM32系列的MCU分?jǐn)?shù)
2025-07-12 12:38:52
【開(kāi)箱】
感謝 elecfans 和 賽昉半導(dǎo)體 的測(cè)評(píng)活動(dòng),收到了 VisionFive 2 開(kāi)發(fā)板,先上圖一睹為快。
【處理器介紹】
這款開(kāi)發(fā)板搭載 28nm StarFive
2025-07-12 10:43:25
睿莓1是一款性能優(yōu)異且極具性價(jià)比,專(zhuān)為多種應(yīng)用場(chǎng)景設(shè)計(jì)的單板計(jì)算機(jī)。搭載Amlogic S905X4四核處理器,支持多種內(nèi)存和存儲(chǔ)配置,配備HDMI 2.1接口,支持4Kp75視頻輸出。它具備10
2025-07-11 16:48:41
工業(yè)計(jì)算機(jī)是一種專(zhuān)為工廠和工業(yè)環(huán)境設(shè)計(jì)的計(jì)算系統(tǒng),具有高可靠性和穩(wěn)定性,能夠應(yīng)對(duì)惡劣環(huán)境下的自動(dòng)化、制造和機(jī)器人操作。其特點(diǎn)包括無(wú)風(fēng)扇散熱技術(shù)、無(wú)電纜連接和防塵防水設(shè)計(jì),使其在各種工業(yè)自動(dòng)化場(chǎng)景中
2025-07-10 16:36:44
587 
適用場(chǎng)景 :RVspace防-星光2單板計(jì)算機(jī)(Debian11),SD卡根分區(qū)擴(kuò)容
核心原理
三步操作流程 : graph LR
A[刪除舊分區(qū)] --> B[重建分區(qū)-保持起始扇區(qū)
2025-07-09 20:50:19
一、環(huán)境搭建
相關(guān)命令來(lái)源:GitHub -
starfive-tech/VisionFive2
注意:整個(gè)環(huán)境搭建過(guò)程都需要vpn,否則ubuntu鏡像無(wú)法下載,代碼無(wú)法抓取,編譯中間的工具無(wú)法抓取。
1.1 下載docker及鏡像
docker pull ubuntu:20.04
cmd窗口執(zhí)行命令抓取ubuntu鏡像。
抓取好后在docker界面看到images欄新增了一個(gè)ubuntu的鏡像
1.2 區(qū)分大小寫(xiě)
【很重要!?。≡O(shè)置區(qū)分大小寫(xiě)】
這個(gè)很重要,否則會(huì)導(dǎo)致編譯buildroot_rootfs失敗
失敗提示“__lll_lock_wake_private”
參考:https://stackoverflow.com/questions/61059870/what-is-lll-lock-wait-private-and-what-can-cause-a-hang-while-malloc-consolida
創(chuàng)建一個(gè)文件夾存放docker項(xiàng)目D:\\\\docker_pro\\\\c_visionfive2,注意設(shè)置區(qū)分大小寫(xiě)
執(zhí)行命令區(qū)分大小寫(xiě)
fsutil.exe file setCaseSensitiveInfo D:\\\\docker_pro\\\\c_visionfive2 enable
可以在D:\\\\docker_pro目錄中,創(chuàng)建兩個(gè)文件夾分別是a和A,如果都可以存在則表明設(shè)置成功。
1.3 生成容器
執(zhí)行完后則進(jìn)入容器
docker run --name c_visionfive2 -v //d/docker_pro/c_visionfive2:/home -it ubuntu:20.04 /bin/bash
解釋?zhuān)哼@里的//d/docker_pro/c_visionfive2是你要在windows中查看的文件路徑,/home是這個(gè)文件映射在容器中的路徑
docker container ls -a
docker exec -it c_visionfive2 /bin/bash
也可以用上述兩個(gè)命令進(jìn)入容器,先查看所有容器,然后輸入容器名
docker exec -it<container_name> /bin/bash
PS:需要注意在docker中先把容器狀態(tài)設(shè)置為運(yùn)行。
1.4 更新工具
更新ubunut工具,如果不運(yùn)行,git就沒(méi)法用
apt update
下載依賴apt-get -y install build-essential automake libtool texinfo bison flex gawk g++ git xxd curl wget gdisk gperf cpio bc screen texinfo unzip libgmp-dev libmpfr-dev libmpc-dev libssl-dev libncurses-dev libglib2.0-dev libpixman-1-dev libyaml-dev patchutils python3-pip zlib1g-dev device-tree-compiler dosfstools mtools kpartx rsync
輸入6和70選擇時(shí)區(qū)
安裝工具git-lfs
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash
apt-get install git-lfs
二、抓取代碼
可以直接將如下代碼塊存成setup.sh文件,注意LF結(jié)尾
拷貝到/home目錄下,直接運(yùn)行./setup.sh
如果網(wǎng)絡(luò)給力的話,可以一次性運(yùn)行成功。
如果不行可以按步驟依次執(zhí)行。
git clone https://github.com/starfive-tech/VisionFive2.git
cd VisionFive2
git checkout --track origin/JH7110_VisionFive2_devel
git submodule update --init --recursive
cd linux
git branch JH7110_VisionFive2_devel origin/JH7110_VisionFive2_devel
cd ../buildroot
git checkout --track origin/JH7110_VisionFive2_devel
cd ../u-boot
git checkout --track origin/JH7110_VisionFive2_devel
cd ../linux
git checkout --track origin/JH7110_VisionFive2_devel
cd ../opensbi
git checkout --track origin/JH7110_VisionFive2_devel
cd ../soft_3rdpart
git checkout JH7110_VisionFive2_devel
cd ..
make -j$(nproc)
三、編譯結(jié)果
四、異?!粎^(qū)分大小寫(xiě)導(dǎo)致
會(huì)遇到__lll_lock_wait_private的提示
如果沒(méi)有事先把文件夾設(shè)置為區(qū)分大小寫(xiě),后期想再設(shè)置就會(huì)失敗。
五、刷機(jī)
暫時(shí)沒(méi)找到直觀的整編刷機(jī)教程,下期發(fā)布。
2025-07-08 23:07:14
2h........無(wú)奈)
參考文獻(xiàn):
全球首款集成3D GPU的高性能量產(chǎn)RISC-V 單板計(jì)算機(jī),昉·星光 2 開(kāi)發(fā)實(shí)踐![全球首款集成3D GPU的高性能量產(chǎn)RISC-V 單板計(jì)算機(jī),昉·星光 2 開(kāi)發(fā)實(shí)踐
2025-07-06 23:28:57
使用opencv測(cè)試USB攝像頭。
一、檢測(cè)USB攝像頭
插入U(xiǎn)SB攝像頭,執(zhí)行命令,提示沒(méi)有找到命令
root@starfive:~# lsusb
安裝軟件包
root@starfive:~# sudo apt install usbutils
再次執(zhí)行,找到USB攝像頭設(shè)備
二、檢測(cè)攝像頭參數(shù)
2.1、安裝v4l2-ctl工具,查看視頻設(shè)備
root@starfive:~# sudo apt install v4l-utils
root@starfive:~# v4l2-ctl --list-device
2.2、查看指定視頻設(shè)備參數(shù)信息
root@starfive:~# v4l2-ctl --device=/dev/video4 --all
三、測(cè)試圖像
3.1、安裝依賴軟件包
root@starfive:/opt# sudo apt-get install python3-pip
root@starfive:/opt# sudo apt-get install libopencv-dev python3-opencv
3.2、測(cè)試代碼
import cv2
cap = cv2.VideoCapture(4)
while True:
ret, frame = cap.read()
cv2.imshow(\"Camera\", frame)
if cv2.waitKey(1) & 0xFF == ord(\'q\'):
break
cap.release()
cv2.destroyAllWindows()
3.3、顯示圖像
2025-07-06 23:14:24
測(cè)試遠(yuǎn)程訪問(wèn)開(kāi)發(fā)板界面
一、安裝vncserver軟件
user@starfive:~$ sudo apt install xfce4 xfce4-goodies
user@starfive:~$ sudo apt install tightvncserver
二、運(yùn)行軟件
2.1、創(chuàng)建登錄密碼
user@starfive:~$ vncserver
2.2、修改xstartup文件
user@starfive:~$ vi .vnc/xstartup
在文件最后增加startxfce4 &
三、遠(yuǎn)程桌面登錄
3.1、選擇VNC方式登錄
3.2、輸入創(chuàng)建的密碼
3.3、登錄后的界面
3.4、修改分辨率
默認(rèn)顯示分辨率有點(diǎn)低,登錄時(shí)可以設(shè)置顯示的分辨率
關(guān)閉掉上次打開(kāi)的進(jìn)程
user@starfive:~$ vncserver -kill :1
以1920*1080分辨率打開(kāi)
user@starfive:~$ vncserver -geometry 1920x1080
2025-07-06 08:47:55
官方有VisionFive.gpio,嘗試下移植libgpiod到開(kāi)發(fā)板。
一、安裝GPIO庫(kù)
1.1、下載源碼
執(zhí)行命令:
root@starfive:~# wget https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/snapshot/libgpiod-2.0.tar.gz
root@starfive:~# tar xvf libgpiod-2.0.tar.gz
root@starfive:~# apt-get install build-essential pkg-config m4 automake autoconf libtool autoconf-archive
root@starfive:~# apt-get install gcc g++
root@starfive:~# export CC=gcc
root@starfive:~# export CXX=g++
1.2、安裝
root@starfive:~/libgpiod-2.0# ./autogen.sh --enable-tools=yes --prefix=/root/starfive/mylib_local
root@starfive:~/libgpiod-2.0# make
root@starfive:~/libgpiod-2.0# make install
安裝完成后,生成的文件
二、測(cè)試
2.1、gpio.c
//#gpio.c
#include<stdio.h>
#include<unistd.h>
#include<gpiod.h>
#define PIN_IO2_4646//LD0
#define PIN_IO2_4444//LD1
#define PIN_IO2_6161//LD2
#define PIN_IO2_6363//ld3
#define PIN_IO2_4242//K2
int main()
{
struct gpiod_chip *gchip;
struct gpiod_line_info *glinein, *glineout;
struct gpiod_line_settings *gline_settings_in, *gline_settings_out;
struct gpiod_line_config*gline_config_in, *gline_config_out;
struct gpiod_request_config *gline_request_config_in, *gline_request_config_out;
struct gpiod_line_request*gline_request_in, *gline_request_out;
int offset_in[1] = {PIN_IO2_42};
int offset_out[4] = {PIN_IO2_44, PIN_IO2_46, PIN_IO2_61, PIN_IO2_63};
int value;
if ((gchip=gpiod_chip_open(\"/dev/gpiochip0\")) == NULL)
{
perror(\"gpiod_chip_open\");
return 1;
}
gline_settings_in = gpiod_line_settings_new();
if ((value=gpiod_line_settings_set_direction(gline_settings_in, GPIOD_LINE_DIRECTION_INPUT)) != 0)
{
perror(\"gpiod_line_settings_set_direction\");
}
gline_config_in = gpiod_line_config_new();
value=gpiod_line_config_add_line_settings(gline_config_in, offset_in, 1, gline_settings_in);
gline_request_config_in = gpiod_request_config_new();
gline_request_in = gpiod_chip_request_lines(gchip, gline_request_config_in, gline_config_in);
gline_settings_out = gpiod_line_settings_new();
if (gpiod_line_settings_set_direction(gline_settings_out, GPIOD_LINE_DIRECTION_OUTPUT) != 0)
{
perror(\"gpiod_line_settings_set_direction\");
}
gline_config_out = gpiod_line_config_new();
gpiod_line_config_add_line_settings(gline_config_out, offset_out, 4, gline_settings_out);
gline_request_config_out = gpiod_request_config_new();
gline_request_out = gpiod_chip_request_lines(gchip, gline_request_config_out, gline_config_out);
value=gpiod_line_request_set_value(gline_request_out, PIN_IO2_46, 0);
value=gpiod_line_request_set_value(gline_request_out, PIN_IO2_44, 1);
value=gpiod_line_request_set_value(gline_request_out, PIN_IO2_61, 0);
value=gpiod_line_request_set_value(gline_request_out, PIN_IO2_63, 1);
sleep(1);
for (int i = 0; i < 50; i++) {
//value=gpiod_line_request_get_value(gline_request_in, PIN_IO2_42);
//printf(\"PIN_IO2_42 = %d\\\\\\\\n\", value);
gpiod_line_request_set_value(gline_request_out, PIN_IO2_46, 1);
gpiod_line_request_set_value(gline_request_out, PIN_IO2_44, 0);
gpiod_line_request_set_value(gline_request_out, PIN_IO2_61, 1);
gpiod_line_request_set_value(gline_request_out, PIN_IO2_63, 0);
sleep(1);
gpiod_line_request_set_value(gline_request_out, PIN_IO2_46, 0);
gpiod_line_request_set_value(gline_request_out, PIN_IO2_44, 1);
gpiod_line_request_set_value(gline_request_out, PIN_IO2_61, 0);
gpiod_line_request_set_value(gline_request_out, PIN_IO2_63, 1);
sleep(1);
}
gpiod_chip_close(gchip);
return 0;
}
2.2、編譯代碼
在gpio.c所在的目錄下編譯
命令:root@starfive:~# gcc-I/root/starfive/mylib_local/include -L/root/starfive/mylib_local/lib -o gpio gpio.c -lgpiod
2.3、設(shè)置路徑
root@starfive:~# export LD_LIBRARY_PATH=/root/starfive/mylib_local/lib:$LD_LIBRARY_PATH
root@starfive:~# export PATH=/root/starfive/mylib_local/bin:$PATH
三、運(yùn)行結(jié)果
運(yùn)行命令:root@starfive:~# ./gpio
2025-07-02 07:16:36
如果計(jì)算的未來(lái)不是被鎖定在專(zhuān)有架構(gòu)上,那會(huì)怎樣?想象一下,在這個(gè)世界上,開(kāi)發(fā)人員和業(yè)余愛(ài)好者都可以利用開(kāi)源硬件的強(qiáng)大功能自由構(gòu)建、創(chuàng)新和實(shí)驗(yàn)。進(jìn)入RISC-V單板計(jì)算機(jī)(SBC)領(lǐng)域——一個(gè)新興
2025-06-30 13:35:59
1020 
測(cè)試板卡GPIO口點(diǎn)亮LED燈。
一、搭建環(huán)境
1.1、文檔
按照官方的應(yīng)用文檔搭建測(cè)試環(huán)境GPIO點(diǎn)亮LED
1.2、在Debain系統(tǒng)上安裝piproot@starfive:~# apt-get install python3-pip
1.3、安裝VisionFive.gpio包
1.3.1、安裝依賴包
apt install libxml2-dev libxslt-dev
python3 -m pip install requests wget bs4
安裝過(guò)程中遇到點(diǎn)問(wèn)題
報(bào)錯(cuò):error: externally-managed-environment
執(zhí)行命令apt install python3-requests python3-wget python3-bs4 -y
正常安裝
1.3.2、運(yùn)行安裝腳本
下載最新的VisionFive.gpio
下載地址:VisionFive.gpio
該版本有三個(gè)下載鏈接
根據(jù)系統(tǒng)安裝的python版本來(lái)選擇,選擇系統(tǒng)版本對(duì)應(yīng)的python 3.11
執(zhí)行下載命令:
wget https://files.pythonhosted.org/packages/2e/00/16326e8e01a268ce997b72e70240d7249a550222af82955d9b4a52f8a320/VisionFive.gpio-1.3.3-cp311-cp311-any.whl
修改文件名:mv VisionFive.gpio-1.3.3-cp311-cp311-any.whl VisionFive.gpio-1.3.3-cp311-cp311-linux_riscv64.whl
安裝python3 -m pip install VisionFive.gpio-1.3.3-cp311-cp311-linux_riscv64.whl --break-system-packages
二、測(cè)試
找到測(cè)試代碼的位置
2.1、查看VisionFive.gpio安裝的目錄pip show VisionFive.gpio
進(jìn)入目錄
cd /usr/local/lib/python3.11/dist-packages/
cd VisionFive/sample-code/
找到led.py
2.2、修改測(cè)試代碼
根據(jù)測(cè)試的硬件修改對(duì)應(yīng)的端口
這里測(cè)試使用GPIO44端口,對(duì)用引腳號(hào)為40
修改led.py
\"\"\"
Please make sure the LED is connected to the correct pins.
The following table describes how to connect the LED to the 40-pin header.
-----------------------------------------
_______LED_________Pin Number_____Pin Name
Positive 22 GPIO50
Negative 6GND
-----------------------------------------
\"\"\"
import VisionFive.gpio as GPIO
import time
led_pin = 40
# Set the gpio mode as \'BOARD\'.
GPIO.setmode(GPIO.BOARD)
# Configure the direction of led_pin as output.
GPIO.setup(led_pin, GPIO.OUT)
def light(delay):
# Configure the voltage level of led_pin as high.
GPIO.output(led_pin, GPIO.HIGH)
time.sleep(delay)
# Configure the voltage level of led_pin as low.
GPIO.output(led_pin, GPIO.LOW)
time.sleep(delay)
if __name__ == \"__main__\":
try:
delay_s = input(\"Enter delay(seconds): \")
delay = float(delay_s)
while True:
try:
light(delay)
except KeyboardInterrupt:
break
finally:
GPIO.cleanup()
2.3、運(yùn)行
執(zhí)行命令:python3 led.py提示輸入延時(shí)時(shí)間
2.4、運(yùn)行結(jié)果
運(yùn)行后,LED燈閃爍
2025-06-30 07:31:21
板卡上默認(rèn)是沒(méi)有系統(tǒng),需要將系統(tǒng)燒寫(xiě)到TF卡、EMMC或M2硬盤(pán)上。
一、固件下載
下載地址:https://debian.starfivetech.com/
選址最新發(fā)布的版本
二、格式化TF卡
使用軟件SD Formatter格式化TF卡*附件:SD Formatter.zip
三、安裝鏡像
3.1、下載軟件balenaEtcher
使用balenaEtcher軟件安裝系統(tǒng)鏡像
軟件下載地址:balenaEtcher
3.2、安裝鏡像
下載的系統(tǒng),使用SD目錄下的鏡像文件
解壓鏡像文件
燒錄鏡像
四、啟動(dòng)系統(tǒng)
4.1、設(shè)置啟動(dòng)模式
將燒寫(xiě)完成的TF卡插入開(kāi)發(fā)板,設(shè)置為SD方式啟動(dòng)。
4.2、啟動(dòng)運(yùn)行
啟動(dòng)后,輸入用戶名:user密碼:starfive ,進(jìn)入系統(tǒng)。
2025-06-29 22:36:47
收到開(kāi)發(fā)板了,開(kāi)箱開(kāi)始了解開(kāi)發(fā)板。
一、開(kāi)箱
開(kāi)發(fā)板包裝很精致,外面一層塑料膜。
內(nèi)部是塑料盒
里面是開(kāi)發(fā)板
二、板卡資料
地址:鏈接
板卡上沒(méi)有FLASH存儲(chǔ)器,上電后也沒(méi)有反應(yīng)。
2025-06-29 19:07:15
在x86與ARM架構(gòu)主導(dǎo)的單板計(jì)算機(jī)市場(chǎng),中國(guó)團(tuán)隊(duì)打造的VisionFive 2(防星光2)如同一顆新星,憑借開(kāi)源開(kāi)放的RISC-V架構(gòu)和成熟的桌面體驗(yàn),為開(kāi)發(fā)者與極客提供了全新的選擇。經(jīng)過(guò)
2025-06-27 09:06:10
現(xiàn)代高性能計(jì)算不僅使得更快的計(jì)算成為可能,它正驅(qū)動(dòng)著 AI 系統(tǒng)解鎖更多領(lǐng)域的科學(xué)突破。 高性能計(jì)算經(jīng)歷了多次迭代,每一次都源于對(duì)技術(shù)的創(chuàng)造性再利用。例如,早期的超級(jí)計(jì)算機(jī)使用現(xiàn)成的組件制造。后來(lái)
2025-06-26 19:39:00
1083 
燒錄系統(tǒng)
下載img,解壓出來(lái)的img文件大約4G。
用Rufus,把img文件燒錄到TF卡中
這一步可以使用的軟件很多,大家都可以試試,不行就換一個(gè)官方手冊(cè)用的。
開(kāi)箱
特性
VisionFive (初代)
VisionFive 2
SoC
StarFive JH7100
StarFive JH7110
CPU
雙核 SiFive U74 @ 1.5GHz
四核 SiFive U74 @ 1.5GHz
GPU
無(wú)獨(dú)立 GPU
Imagination PowerVR GPU
AI 加速
無(wú)
0.5 TOPS NPU
內(nèi)存
2GB/4GB LPDDR4
2GB/4GB/8GB LPDDR4
存儲(chǔ)
MicroSD, SPI Flash
eMMC 插槽 + MicroSD + SPI Flash
視頻輸出
HDMI 1.4 (1080p)
HDMI 2.0 (4K@30fps)
網(wǎng)絡(luò)
千兆以太網(wǎng)
雙千兆以太網(wǎng)
無(wú)線
Wi-Fi 5 + 藍(lán)牙 5.2
無(wú)
VisionFive 2 相比第一代全面升級(jí),只是燒錄WiFi模塊,但是雙千兆網(wǎng)口,USB3.0可以外接無(wú)線網(wǎng)卡。
啟動(dòng)
外接了顯示器 鼠標(biāo) 鍵盤(pán) 千兆以太網(wǎng)
gnome的桌面 Wayland顯示。
同時(shí)打開(kāi)4個(gè)應(yīng)用,CPU占用也不高。所以瓶頸在TF卡的讀寫(xiě)速度。cpu還是挺強(qiáng)的。
高性能板卡整體發(fā)熱還是很明顯的,推薦增加散熱片,或者風(fēng)扇主動(dòng)散熱,最好2者都加上。
2025-06-26 18:20:40
歡迎的單板計(jì)算機(jī)之一。你可能已經(jīng)擁有一臺(tái)了,不是嗎?Android是世界上最流行的操作系統(tǒng),擁有各種各樣的應(yīng)用程序可供選擇。這種流行度,再加上樹(shù)莓派日益增強(qiáng)的性能,為在樹(shù)莓派上
2025-06-18 17:20:37
588 
德國(guó)萊布尼茨超算中心(LRZ)將迎來(lái)全新超級(jí)計(jì)算機(jī) Blue Lion,其算力比該中心現(xiàn)有的 SuperMUC-NG 高性能計(jì)算機(jī)提升了約 30 倍。這臺(tái)新的超級(jí)計(jì)算機(jī)將在 NVIDIA Vera Rubin 架構(gòu)上運(yùn)行。
2025-06-12 15:39:45
924 NVIDIA 宣布,搭載 NVIDIA Grace Hopper 平臺(tái)的 JUPITER 超級(jí)計(jì)算機(jī)成為歐洲最快超級(jí)計(jì)算機(jī),其運(yùn)行 HPC 和 AI 工作負(fù)載的速度是第二名的兩倍以上。
2025-06-12 15:33:36
1207 感謝海內(nèi)外開(kāi)發(fā)者的使用反饋和建議,進(jìn)迭時(shí)空針對(duì)MUSEPi進(jìn)行了全面升級(jí),推出全新1.8寸單板計(jì)算機(jī)--MUSEPiPro(以下簡(jiǎn)稱PiPro)。升級(jí)后的PiPro將RISC-VAICPU芯片K1
2025-06-06 16:55:42
1099 
環(huán)旭電子作為全球電子設(shè)計(jì)與制造服務(wù)領(lǐng)導(dǎo)廠商,近年來(lái)透過(guò)聯(lián)合設(shè)計(jì)制造服務(wù)模式(Joint Design Manufacturing,JDM),協(xié)助知名品牌客戶開(kāi)發(fā)出兼具強(qiáng)固性與高效能的自行車(chē)計(jì)算機(jī),以滿足全世界自行車(chē)計(jì)算機(jī)市場(chǎng)日益成長(zhǎng)的需求。
2025-06-04 18:17:45
797 如果你是搞工業(yè)自動(dòng)化、醫(yī)療設(shè)備、交通控制,甚至是軍事裝備的,那你大概率已經(jīng)聽(tīng)過(guò)“模塊化計(jì)算機(jī)”這個(gè)詞。要是你還沒(méi)了解,那這篇文章就是為你寫(xiě)的。作為一個(gè)在工業(yè)計(jì)算領(lǐng)域摸爬滾打十多年的從業(yè)者,我可以很負(fù)責(zé)任地說(shuō):模塊化計(jì)算機(jī)不是未來(lái)趨勢(shì),它就是現(xiàn)在現(xiàn)實(shí)。
2025-06-04 11:00:08
843 
機(jī)器人設(shè)計(jì)是一個(gè)跨學(xué)科的領(lǐng)域,涉及機(jī)械工程、電子工程、計(jì)算機(jī)科學(xué)、人工智能、材料科學(xué)等多個(gè)學(xué)科。主要電子與控制系統(tǒng)核心控制器:微控制器(Arduino、STM32)、單板計(jì)算機(jī)
2025-05-22 11:41:30
578 
NVIDIA 宣布將開(kāi)設(shè)量子-AI 技術(shù)商業(yè)應(yīng)用全球研發(fā)中心(G-QuAT),該中心部署了全球最大量子計(jì)算研究專(zhuān)用超級(jí)計(jì)算機(jī) ABCI-Q。
2025-05-22 09:44:15
756 工業(yè)計(jì)算機(jī)是為挑戰(zhàn)消費(fèi)級(jí)系統(tǒng)耐用性的環(huán)境而構(gòu)建的。在制造業(yè)、運(yùn)輸業(yè)、國(guó)防和采礦業(yè)等領(lǐng)域,計(jì)算機(jī)面臨著持續(xù)的沖擊、振動(dòng)和其他物理壓力。設(shè)計(jì)這些系統(tǒng)以在這種條件下保持可靠需要卓越的工程和創(chuàng)新技術(shù)。本文
2025-05-19 15:27:59
397 
IVA的好處、實(shí)際部署應(yīng)用程序以及工業(yè)計(jì)算機(jī)如何實(shí)現(xiàn)這些解決方案。一、什么是智能視頻分析(IVA)?智能視頻分析(IVA)集成了復(fù)雜的計(jì)算機(jī)視覺(jué),通常與卷積神經(jīng)網(wǎng)
2025-05-16 14:37:14
695 
工業(yè)計(jì)算機(jī)尺寸的關(guān)鍵差異化因素工業(yè)計(jì)算機(jī)的尺寸因應(yīng)用要求、環(huán)境限制和性能能力而異。以下是區(qū)分它們的關(guān)鍵因素:物理尺寸(寬度、深度和高度):確定系統(tǒng)是否適合空間受限的機(jī)柜、控制面板或機(jī)架??蓴U(kuò)展性
2025-04-27 12:10:45
558 
一項(xiàng)艱巨的任務(wù)。本博客將指導(dǎo)您了解關(guān)鍵的工業(yè)計(jì)算機(jī)尺寸、使用案例。關(guān)鍵工業(yè)計(jì)算機(jī)外形要素及其使用案例一、工業(yè)微型PC尺寸范圍:寬度:100毫米-180毫米深度:10
2025-04-24 13:35:25
871 
計(jì)算機(jī)網(wǎng)絡(luò)是指將地理位置不同且具有獨(dú)立功能的多臺(tái)計(jì)算機(jī)及其外部設(shè)備,通過(guò)通信線路連接起來(lái),在網(wǎng)絡(luò)操作系統(tǒng)、網(wǎng)絡(luò)管理軟件及網(wǎng)絡(luò)通信協(xié)議的管理和協(xié)調(diào)下,實(shí)現(xiàn)資源共享和信息傳遞的計(jì)算機(jī)系統(tǒng)。
2025-04-22 14:29:55
1952 
OrangePi和RaspberryPi介紹RaspberryPi:現(xiàn)代單板計(jì)算機(jī)的先驅(qū)RaspberryPi是由英國(guó)RaspberryPi基金會(huì)開(kāi)發(fā)的一款單板計(jì)算機(jī),自2012年發(fā)布以來(lái),其目標(biāo)
2025-04-10 15:52:38
1002 
產(chǎn)品介紹龍芯3A6000信創(chuàng)臺(tái)式計(jì)算機(jī),型號(hào):HJ910L華頡科技提供的國(guó)產(chǎn)龍芯3A6000信創(chuàng)臺(tái)式計(jì)算機(jī),搭載龍芯3A6000處理器的國(guó)產(chǎn)化主板,配套國(guó)產(chǎn)BIOS、國(guó)產(chǎn)桌面操作系統(tǒng)、應(yīng)用軟件,實(shí)現(xiàn)
2025-03-31 15:32:19
產(chǎn)品介紹 兆芯KX-6000信創(chuàng)臺(tái)式計(jì)算機(jī),型號(hào):HJ910Z華頡科技提供的國(guó)產(chǎn)兆芯KX-6000信創(chuàng)臺(tái)式計(jì)算機(jī),搭載兆芯KX-U6780A處理器的國(guó)產(chǎn)化主板,配套國(guó)產(chǎn)BIOS、國(guó)產(chǎn)桌面
2025-03-31 15:28:26
產(chǎn)品介紹海光3350信創(chuàng)臺(tái)式計(jì)算機(jī),型號(hào):HJ910H華頡科技提供的國(guó)產(chǎn)海光3350信創(chuàng)臺(tái)式計(jì)算機(jī),搭載海光3350處理器的國(guó)產(chǎn)化主板,配套國(guó)產(chǎn)BIOS、國(guó)產(chǎn)桌面操作系統(tǒng)、應(yīng)用軟件,實(shí)現(xiàn)國(guó)產(chǎn)化
2025-03-31 15:23:37
產(chǎn)品介紹飛騰D2000信創(chuàng)臺(tái)式計(jì)算機(jī),型號(hào):HJ910F華頡科技提供的國(guó)產(chǎn)飛騰D2000信創(chuàng)臺(tái)式計(jì)算機(jī),搭載飛騰D2000處理器的國(guó)產(chǎn)化主板,配套國(guó)產(chǎn)BIOS、國(guó)產(chǎn)桌面操作系統(tǒng)、應(yīng)用軟件,實(shí)現(xiàn)國(guó)產(chǎn)化
2025-03-31 15:18:55
觀看下方視頻,詳細(xì)了解RaspberryPi運(yùn)行LLM的效果(作為編程助手),以及RaspberryPi5與內(nèi)置NPU的單板計(jì)算機(jī)(如RadxaRock5C)的性能
2025-03-27 15:44:37
602 
RaspberryPi是一款超級(jí)實(shí)惠的單板計(jì)算機(jī)(SBC),可用于各種不同的項(xiàng)目。RaspberryPi的一些最流行用途包括將其變成媒體播放器或模擬機(jī)器。鑒于該系統(tǒng)的多功能性,有人想知道它是否可以
2025-03-25 09:43:58
1065 
上海晶珩的ED-IPC3100系列是基于新型RaspberryPiCM5(計(jì)算模塊5)的四款DIN導(dǎo)軌安裝式工業(yè)計(jì)算機(jī),配有兩個(gè)以太網(wǎng)端口,以及各種RS232或RS485COM端口選項(xiàng),具體取決于
2025-03-25 09:33:15
897 
注意:可以點(diǎn)擊文章底部的閱讀原文來(lái)查看原文章作為最突出的單板計(jì)算機(jī)(SBC)系列,RaspberryPi系列兼容眾多操作系統(tǒng)。諸如KaliLinux、Ubuntu、Debian和功能強(qiáng)大
2025-03-25 09:29:20
1157 
如果你需要一臺(tái)小型且經(jīng)濟(jì)實(shí)惠的電腦來(lái)完成個(gè)人項(xiàng)目,那么現(xiàn)在正是最佳時(shí)機(jī)。單板計(jì)算機(jī)市場(chǎng)價(jià)值30億美元,預(yù)計(jì)未來(lái)十年將持續(xù)增長(zhǎng)。這意味著有很多選擇,但除非你有非常具體的需求,否則在考慮其他選項(xiàng)之前,有
2025-03-25 09:27:52
646 
凱澤斯勞滕理工大學(xué)通過(guò)引入先進(jìn)的德思特任意波形發(fā)生器(AWG)新DDS固件選件,顯著加速了量子計(jì)算機(jī)的開(kāi)發(fā)進(jìn)程。德思特帶您了解AWG全新DDS固件如何提升量子計(jì)算機(jī)的開(kāi)發(fā)效率。
2025-03-21 16:50:58
646 
臺(tái)式超級(jí)計(jì)算機(jī)由 NVIDIA Grace Blackwell 驅(qū)動(dòng),為開(kāi)發(fā)者、研究人員和數(shù)據(jù)科學(xué)家提供加速 AI 功能;系統(tǒng)由頭部計(jì)算機(jī)制造商(包括華碩、Dell Technologies、HP
2025-03-19 09:59:29
536 
行業(yè)聚焦深圳計(jì)算機(jī)協(xié)會(huì)走進(jìn)杰和2025年2月28日,深圳市計(jì)算機(jī)行業(yè)協(xié)會(huì)在杰和科技召開(kāi)會(huì)長(zhǎng)辦公(擴(kuò)大)會(huì)議及領(lǐng)導(dǎo)干部知識(shí)產(chǎn)權(quán)培訓(xùn)會(huì)。會(huì)議匯聚黨支部、理事會(huì)、監(jiān)事會(huì)及行業(yè)領(lǐng)軍企業(yè)等40余代表,共同研判
2025-03-05 10:04:53
660 
在特殊的工業(yè)環(huán)境中,實(shí)現(xiàn)快速生產(chǎn)離不開(kāi)各類(lèi)工業(yè)計(jì)算機(jī)的強(qiáng)大支持。杰和科技工業(yè)計(jì)算機(jī)AF208,作為核心控制單元,憑借其堅(jiān)固可靠的外殼、先進(jìn)的散熱技術(shù)以及緊湊靈活的部署特點(diǎn),發(fā)揮著關(guān)鍵作用。硬實(shí)力外殼
2025-03-03 11:04:12
649 
日前,全球知名科技媒體How-toGeek評(píng)選2025年最佳單板計(jì)算機(jī),該媒體共評(píng)選出5款最佳單板計(jì)算機(jī),香橙派占據(jù)其中兩個(gè)席位,入選的產(chǎn)品是:OrangePi5Plus、OrangePi5。此外
2025-02-28 13:38:04
1796 
DFRobotLattePandaMu被全球知名科技媒體How-toGeek評(píng)選為2025年最佳Windows單板計(jì)算機(jī)。單板計(jì)算機(jī)(SBC)為有創(chuàng)意的用戶和愛(ài)好者提供了一個(gè)絕佳的方式,可以讓他們
2025-02-21 16:57:31
1447 
近日,東京——全球領(lǐng)先的集成量子計(jì)算公司Quantinuum與日本頂尖的綜合研究機(jī)構(gòu)RIKEN共同宣布,Quantinuum的“Reimei”量子計(jì)算機(jī)已在RIKEN Wako園區(qū)(位于日本埼玉縣
2025-02-17 10:21:32
856 BU-67121W實(shí)驗(yàn)室航空電子接口計(jì)算機(jī)North HillsNorth Hills的航空電子接口計(jì)算機(jī)(AIC),即BU-67121W,是一個(gè)高效能、可擴(kuò)展且便攜的平臺(tái),專(zhuān)為通過(guò)以太網(wǎng)開(kāi)發(fā)并測(cè)試
2025-02-11 09:26:19
):計(jì)算機(jī)視覺(jué)引領(lǐng)混合現(xiàn)實(shí)體驗(yàn)增強(qiáng)現(xiàn)實(shí)(AR)和虛擬現(xiàn)實(shí)(VR)正在徹底改變我們與外部世界的互動(dòng)方式。即便是在引人入勝的沉浸式
2025-02-08 14:29:51
2260 
近日,據(jù)報(bào)道,日本國(guó)立產(chǎn)業(yè)技術(shù)綜合研究所(AIST)與全球芯片巨頭英特爾公司正攜手合作,致力于開(kāi)發(fā)下一代量子計(jì)算機(jī)。這一舉措預(yù)示著量子計(jì)算領(lǐng)域?qū)⒂瓉?lái)新的突破。 據(jù)了解,此次合作將充分利用英特爾在芯片
2025-02-07 14:26:02
834 2025年1月8日,深圳市計(jì)算機(jī)行業(yè)協(xié)會(huì)舉辦了2024年度會(huì)員大會(huì)暨高峰論壇。杰和科技應(yīng)邀出席會(huì)議,與行業(yè)精英、專(zhuān)家代表等共同探討2025年計(jì)算機(jī)行業(yè)未來(lái)趨勢(shì)。本次大會(huì)現(xiàn)場(chǎng)發(fā)布多項(xiàng)行業(yè)權(quán)威榜單與獎(jiǎng)項(xiàng)
2025-02-05 17:48:39
853 
加州理工學(xué)院的研究人員取得重大突破,開(kāi)發(fā)出一款能實(shí)現(xiàn)超過(guò)100GHz時(shí)鐘速度的全光計(jì)算機(jī)。 長(zhǎng)期以來(lái),電子計(jì)算機(jī)時(shí)鐘頻率在近20年停滯于5GHz左右。 而此次推出的全光計(jì)算機(jī),通過(guò)基于端到端和全光學(xué)
2025-01-23 10:32:49
821 近日,英偉達(dá)在北京舉辦了答謝迎春會(huì),英偉達(dá)創(chuàng)始人兼CEO黃仁勛親臨現(xiàn)場(chǎng)并發(fā)表了致辭。在致辭中,他透露了一個(gè)令人振奮的消息:“我們正處于一個(gè)新時(shí)代的開(kāi)端,一個(gè)重新發(fā)明計(jì)算機(jī)的時(shí)代?!?黃仁勛表示
2025-01-21 10:08:15
716
評(píng)論