RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

使用JavaCV調(diào)用USB攝像頭進(jìn)行實(shí)時(shí)畫面的展示和拍照

OpenCV學(xué)堂 ? 來(lái)源:Java與Android技術(shù)棧 ? 作者:fengzhizi715 ? 2022-10-09 10:26 ? 次閱讀

Part1一. 業(yè)務(wù)背景

我們團(tuán)隊(duì)前段時(shí)間做了一款小型的智能硬件,它能夠自動(dòng)拍攝一些商品的圖片,這些圖片將會(huì)出現(xiàn)在電商 App 的詳情頁(yè)并進(jìn)行展示。

基于以上的背景,我們需要一個(gè)業(yè)務(wù)后臺(tái)用于發(fā)送相應(yīng)的拍照指令,還需要開(kāi)發(fā)一款軟件(上位機(jī))用于接收拍照指令和操作硬件設(shè)備。

Part2二. 原先的實(shí)現(xiàn)方式以及痛點(diǎn)

早期為了快速實(shí)現(xiàn)功能,我們團(tuán)隊(duì)使用 JavaCV 調(diào)用 USB 攝像頭(相機(jī))進(jìn)行實(shí)時(shí)畫面的展示和拍照。這樣的好處在于,能夠快速實(shí)現(xiàn)產(chǎn)品經(jīng)理提出的功能,并快速上線。當(dāng)然,也會(huì)遇到一些問(wèn)題。

我列舉幾個(gè)遇到的問(wèn)題:

軟件體積過(guò)大

編譯速度慢

軟件運(yùn)行時(shí)占用大量的內(nèi)存

對(duì)于獲取的實(shí)時(shí)畫面,不利于在軟件側(cè)(客戶端側(cè))調(diào)用機(jī)器學(xué)習(xí)或者深度學(xué)習(xí)的庫(kù),因?yàn)檎麄€(gè)軟件采用 Java/Kotlin 編寫的。

Part3三. 使用 OpenCV 進(jìn)行重構(gòu)

基于上述的原因,我嘗試用 OpenCV 替代 JavaCV 看看能否解決這些問(wèn)題。

13.1JNI 調(diào)用的設(shè)計(jì)

由于我使用 OpenCV C++ 版本來(lái)進(jìn)行開(kāi)發(fā),因此在開(kāi)發(fā)之前需要先設(shè)計(jì)好應(yīng)用層(我們的軟件主要是采用 Java/Kotlin 編寫的)如何跟 Native 層進(jìn)行交互的一些的方法。比如:USB 攝像頭(相機(jī))的開(kāi)啟和關(guān)閉、拍照、相機(jī)相關(guān)參數(shù)的設(shè)置等等。

為此,設(shè)計(jì)了一個(gè)專門用于圖像處理的類 WImagesProcess(W 是項(xiàng)目的代號(hào)),它包含了上述的方法。

objectWImagesProcess{

init{
System.load("${FileUtil.loadPath}WImagesProcess.dll")
}

/**
*算法的版本號(hào)
*/
externalfungetVersion():String

/**
*獲取OpenCV對(duì)應(yīng)相機(jī)的indexid
*@parampidvid相機(jī)的pid、vid
*/
externalfungetCameraIndexIdFromPidVid(pidvid:String):Int

/**
*開(kāi)啟俯拍相機(jī)
*@paramindex相機(jī)的indexid
*@paramcameraParaMap相機(jī)相關(guān)的參數(shù)
*@paramlistenerjni層給Java層的回調(diào)
*/
externalfunstartTopVideoCapture(index:Int,cameraParaMap:Map,listener:VideoCaptureListener)

/**
*開(kāi)啟側(cè)拍相機(jī)
*@paramindex相機(jī)的indexid
*@paramcameraParaMap相機(jī)相關(guān)的參數(shù)
*@paramlistenerjni層給Java層的回調(diào)
*/
externalfunstartRightVideoCapture(index:Int,cameraParaMap:Map,listener:VideoCaptureListener)

/**
*調(diào)用對(duì)應(yīng)的相機(jī)拍攝照片,使用時(shí)需要將IntArray轉(zhuǎn)換成BufferedImage
*@paramcameraId1:俯拍相機(jī);2:側(cè)拍相機(jī)
*/
externalfuntakePhoto(cameraId:Int):IntArray

/**
*設(shè)置相機(jī)的曝光
*@paramcameraId1:俯拍相機(jī);2:側(cè)拍相機(jī)
*/
externalfunexposure(cameraId:Int,value:Double):Double

/**
*設(shè)置相機(jī)的亮度
*@paramcameraId1:俯拍相機(jī);2:側(cè)拍相機(jī)
*/
externalfunbrightness(cameraId:Int,value:Double):Double

/**
*設(shè)置相機(jī)的焦距
*@paramcameraId1:俯拍相機(jī);2:側(cè)拍相機(jī)
*/
externalfunfocus(cameraId:Int,value:Double):Double

/**
*關(guān)閉相機(jī),釋放相機(jī)的資源
*@paramcameraId1:俯拍相機(jī);2:側(cè)拍相機(jī)
*/
externalfuncloseVideoCapture(cameraId:Int)
}

其中,VideoCaptureListener 是監(jiān)聽(tīng) USB 攝像頭(相機(jī))行為的 Listener。

interfaceVideoCaptureListener{

/**
*Native層調(diào)用相機(jī)成功
*/
funonSuccess()

/**
*jni將Native層調(diào)用相機(jī)獲取每一幀的Mat轉(zhuǎn)換成IntArray,回調(diào)給Java層
*@paramarray回調(diào)給Java層的IntArray,Java層可以將其轉(zhuǎn)化成BufferedImage
*/
funonRead(array:IntArray)

/**
*Native層調(diào)用相機(jī)失敗
*/
funonFailed()
}

VideoCaptureListener#onRead() 方法是在攝像頭(相機(jī))打開(kāi)后,會(huì)實(shí)時(shí)將每一幀的數(shù)據(jù)通過(guò)回調(diào)的形式返回給應(yīng)用層。

23.2 JNI && Native 層的實(shí)現(xiàn)

定義一個(gè) xxx_WImagesProcess.h,它與應(yīng)用層的 WImagesProcess 類對(duì)應(yīng)。

#include

#ifndef_Include_xxx_WImagesProcess
#define_Include_xxx_WImagesProcess
#ifdef__cplusplus
extern"C"{
#endif

JNIEXPORTjstringJNICALLJava_xxx_WImagesProcess_getVersion
(JNIEnv*env,jobject);

JNIEXPORTvoidJNICALLJava_xxx_WImagesProcess_startTopVideoCapture
(JNIEnv*env,jobject,intindex,jobjectcameraParaMap,jobjectlistener);

JNIEXPORTvoidJNICALLJava_xxx_WImagesProcess_startRightVideoCapture
(JNIEnv*env,jobject,intindex,jobjectcameraParaMap,jobjectlistener);

JNIEXPORTjintArrayJNICALLJava_xxx_WImagesProcess_takePhoto
(JNIEnv*env,jobject,intcameraId);

JNIEXPORTdoubleJNICALLJava_xxx_WImagesProcess_exposure
(JNIEnv*env,jobject,intcameraId,doublevalue);

JNIEXPORTdoubleJNICALLJava_xxx_WImagesProcess_brightness
(JNIEnv*env,jobject,intcameraId,doublevalue);

JNIEXPORTdoubleJNICALLJava_xxx_WImagesProcess_focus
(JNIEnv*env,jobject,intcameraId,doublevalue);

JNIEXPORTvoidJNICALLJava_xxx_WImagesProcess_closeVideoCapture
(JNIEnv*env,jobject,intcameraId);

JNIEXPORTintJNICALLJava_xxx_WImagesProcess_getCameraIndexIdFromPidVid
(JNIEnv*env,jobject,jstringpidvid);

#ifdef__cplusplus
}
#endif
#endif
#pragmaonce

xxx 代表的是 Java 項(xiàng)目中 WImagesProcess 類所在的 package 名稱。畢竟是公司項(xiàng)目,我不便貼出完整的 package 名稱。不熟悉這種寫法的,可以參考 JNI 的規(guī)范。

接下來(lái),需要定義一個(gè) xxx_WImagesProcess.cpp 用于實(shí)現(xiàn)上述的方法。

3.2.1 USB 攝像頭(相機(jī))的開(kāi)啟

僅以 startTopVideoCapture() 為例,它的作用是開(kāi)啟智能硬件的俯拍相機(jī),該硬件有 2 款相機(jī)介紹其中一種實(shí)現(xiàn)方式,另一種也很類似。

JNIEXPORTvoidJNICALLJava_xxx_WImagesProcess_startTopVideoCapture
(JNIEnv*env,jobject,intindex,jobjectcameraParaMap,jobjectlistener){
jobjecttopListener=env->NewLocalRef(listener);

std::mapmapOut;
JavaHashMapToStlMap(env,cameraParaMap,mapOut);

jclasslistenerClass=env->GetObjectClass(topListener);
jmethodIDsuccessId=env->GetMethodID(listenerClass,"onSuccess","()V");
jmethodIDreadId=env->GetMethodID(listenerClass,"onRead","([I)V");
jmethodIDfailedId=env->GetMethodID(listenerClass,"onFailed","()V");
jobjectlistenerObject=env->NewLocalRef(listenerClass);


try{
topVideoCapture=wImageProcess.getVideoCapture(index,mapOut);
env->CallVoidMethod(listenerObject,successId);

jintArrayjarray;
topVideoCapture>>topFrame;
int*data=newint[topFrame.total()];
intsize=topFrame.rows*topFrame.cols;
jarray=env->NewIntArray(size);

charr,g,b;

while(topFlag){
topVideoCapture>>topFrame;

for(inti=0;iSetIntArrayRegion(jarray,0,size,(jint*)data);
env->CallVoidMethod(listenerObject,readId,jarray);
waitKey(100);
}
topVideoCapture.release();
env->ReleaseIntArrayElements(jarray,env->GetIntArrayElements(jarray,JNI_FALSE),0);
delete[]data;
}
catch(...){
env->CallVoidMethod(listenerObject,failedId);
}

env->DeleteLocalRef(listenerObject);
env->DeleteLocalRef(topListener);
}

這個(gè)方法用了很多 JNI 相關(guān)的內(nèi)容,接下來(lái)會(huì)簡(jiǎn)單說(shuō)明。

首先,JavaHashMapToStlMap() 方法用于將 Java 的 HashMap 轉(zhuǎn)換成 C++ STL 的 Map。開(kāi)啟相機(jī)時(shí),需要傳遞相機(jī)相關(guān)的參數(shù)。由于相機(jī)需要設(shè)置參數(shù)很多,因此在應(yīng)用層使用 HashMap,傳遞到 JNI 層需要將他們進(jìn)行轉(zhuǎn)化成 C++ 能用的 Map。

voidJavaHashMapToStlMap(JNIEnv*env,jobjecthashMap,std::map&mapOut){
//GettheMap'sentrySet.
jclassmapClass=env->FindClass("java/util/Map");
if(mapClass==NULL){
return;
}
jmethodIDentrySet=
env->GetMethodID(mapClass,"entrySet","()Ljava/util/Set;");
if(entrySet==NULL){
return;
}
jobjectset=env->CallObjectMethod(hashMap,entrySet);
if(set==NULL){
return;
}
//ObtainaniteratorovertheSet
jclasssetClass=env->FindClass("java/util/Set");
if(setClass==NULL){
return;
}
jmethodIDiterator=
env->GetMethodID(setClass,"iterator","()Ljava/util/Iterator;");
if(iterator==NULL){
return;
}
jobjectiter=env->CallObjectMethod(set,iterator);
if(iter==NULL){
return;
}
//GettheIteratormethodIDs
jclassiteratorClass=env->FindClass("java/util/Iterator");
if(iteratorClass==NULL){
return;
}
jmethodIDhasNext=env->GetMethodID(iteratorClass,"hasNext","()Z");
if(hasNext==NULL){
return;
}
jmethodIDnext=
env->GetMethodID(iteratorClass,"next","()Ljava/lang/Object;");
if(next==NULL){
return;
}
//GettheEntryclassmethodIDs
jclassentryClass=env->FindClass("java/util/Map$Entry");
if(entryClass==NULL){
return;
}
jmethodIDgetKey=
env->GetMethodID(entryClass,"getKey","()Ljava/lang/Object;");
if(getKey==NULL){
return;
}
jmethodIDgetValue=
env->GetMethodID(entryClass,"getValue","()Ljava/lang/Object;");
if(getValue==NULL){
return;
}
//IterateovertheentrySet
while(env->CallBooleanMethod(iter,hasNext)){
jobjectentry=env->CallObjectMethod(iter,next);
jstringkey=(jstring)env->CallObjectMethod(entry,getKey);
jstringvalue=(jstring)env->CallObjectMethod(entry,getValue);
constchar*keyStr=env->GetStringUTFChars(key,NULL);
if(!keyStr){
return;
}
constchar*valueStr=env->GetStringUTFChars(value,NULL);
if(!valueStr){
env->ReleaseStringUTFChars(key,keyStr);
return;
}

mapOut.insert(std::make_pair(string(keyStr),string(valueStr)));

env->DeleteLocalRef(entry);
env->ReleaseStringUTFChars(key,keyStr);
env->DeleteLocalRef(key);
env->ReleaseStringUTFChars(value,valueStr);
env->DeleteLocalRef(value);
}
}

接下來(lái)幾行,表示將應(yīng)用層傳遞的 VideoCaptureListener 在 JNI 層需要獲取其類型。然后,查找 VideoCaptureListener 中的幾個(gè)方法,便于后面調(diào)用。這樣 JNI 層就可以跟應(yīng)用層的 Java/Kotlin 進(jìn)行交互了。

jclasslistenerClass=env->GetObjectClass(topListener);
jmethodIDsuccessId=env->GetMethodID(listenerClass,"onSuccess","()V");
jmethodIDreadId=env->GetMethodID(listenerClass,"onRead","([I)V");
jmethodIDfailedId=env->GetMethodID(listenerClass,"onFailed","()V");

接下來(lái),開(kāi)始打開(kāi)攝像頭(相機(jī)),并回調(diào)給應(yīng)用層,這樣 VideoCaptureListener#onSuccess() 方法就能收到回調(diào)。

topVideoCapture=wImageProcess.getVideoCapture(index,mapOut);
env->CallVoidMethod(listenerObject,successId);

打開(kāi)攝像頭(相機(jī))后,就可以實(shí)時(shí)把獲取的每一幀返回給應(yīng)用層。同樣,VideoCaptureListener#onRead() 方法就能收到回調(diào)。

while(topFlag){
topVideoCapture>>topFrame;

for(inti=0;iSetIntArrayRegion(jarray,0,size,(jint*)data);
env->CallVoidMethod(listenerObject,readId,jarray);
waitKey(100);
}

后面的代碼是關(guān)閉相機(jī),釋放資源。

3.2.2 打開(kāi)相機(jī),設(shè)置相機(jī)參數(shù)

在 3.2.1 中,有以下這樣一段代碼:

topVideoCapture=wImageProcess.getVideoCapture(index,mapOut);

它的用途是通過(guò) index id 打開(kāi)對(duì)應(yīng)的相機(jī),并設(shè)置相機(jī)需要的參數(shù),最后返回 VideoCapture 對(duì)象。

VideoCaptureWImageProcess::getVideoCapture(intindex,std::mapcameraParaMap){
VideoCapturecapture(index);

for(auto&t:cameraParaMap){
intkey=stoi(t.first);
doublevalue=stod(t.second);
capture.set(key,value);
}

returncapture;
}

對(duì)于存在同時(shí)調(diào)用多個(gè)相機(jī)的情況,OpenCV 需要基于 index id 來(lái)獲取對(duì)應(yīng)的相機(jī)。那如何獲取 index id 呢?以后有機(jī)會(huì)再寫一篇文章吧。

WImagesProcess 類還額外提供了多個(gè)方法用于設(shè)置相機(jī)的曝光、亮度、焦距等。我們?cè)趩?dòng)相機(jī)的時(shí)候不是可以通過(guò) HashMap 來(lái)傳遞相機(jī)需要的參數(shù)嘛,為何還提供這些方法呢?這樣做的目的是因?yàn)獒槍?duì)不同商品拍照時(shí),可能會(huì)調(diào)節(jié)相機(jī)相關(guān)的參數(shù),因此 WImagesProcess 類提供了這些方法。

3.2.3 拍照

基于 cameraId 來(lái)找到對(duì)應(yīng)的相機(jī)進(jìn)行拍照,并將結(jié)果返回給應(yīng)用層,唯一需要注意的是 C++ 得手動(dòng)釋放資源。

JNIEXPORTjintArrayJNICALLJava_xxx_WImagesProcess_takePhoto
(JNIEnv*env,jobject,intcameraId){

Matmat;
if(cameraId==1){
mat=topFrame;
}
elseif(cameraId==2){
mat=rightFrame;
}

int*data=newint[mat.total()];

charr,g,b;

for(inti=0;iNewIntArray(size);
env->SetIntArrayRegion(jarray,0,size,_data);
delete[]data;
returnjarray;
}

最后,將 CV 程序和 JNI 相關(guān)的代碼最終編譯成一個(gè) dll 文件,供軟件(上位機(jī))調(diào)用,實(shí)現(xiàn)最終的需求。

33.3 應(yīng)用層的調(diào)用

上述代碼寫好后,攝像頭(相機(jī))在應(yīng)用層的打開(kāi)就非常簡(jiǎn)單了,大致的代碼如下:

valmap=HashMap()
map[CAP_PROP_FRAME_WIDTH]=4208.toString()
map[CAP_PROP_FRAME_HEIGHT]=3120.toString()
map[CAP_PROP_AUTO_EXPOSURE]=0.25.toString()
map[CAP_PROP_EXPOSURE]=getTopExposure()
map[CAP_PROP_GAIN]=getTopFocus()
map[CAP_PROP_BRIGHTNESS]=getTopBrightness()
WImagesProcess.startTopVideoCapture(index+CAP_DSHOW,map,object:VideoCaptureListener{
overridefunonSuccess(){
......
}

overridefunonRead(array:IntArray){
......
}

overridefunonFailed(){
......
}
})

應(yīng)用層的拍照也很簡(jiǎn)單:

valbufferedImage=WImagesProcess.takePhoto(cameraId).toBufferedImage()

其中,toBufferedImage() 是 Kotlin 的擴(kuò)展函數(shù)。因?yàn)?takePhoto() 方法返回 IntArray 對(duì)象。

funIntArray.toBufferedImage():BufferedImage{
valdestImage=BufferedImage(FRAME_WIDTH,FRAME_HEIGHT,BufferedImage.TYPE_INT_RGB)
destImage.setRGB(0,0,FRAME_WIDTH,FRAME_HEIGHT,this,0,FRAME_WIDTH)
returndestImage
}

這樣,對(duì)于應(yīng)用層的調(diào)用是非常簡(jiǎn)單的。

Part4四. 總結(jié)

通過(guò) OpenCV 替換 JavaCV 之后,軟件遇到的痛點(diǎn)問(wèn)題基本可以解決。例如軟件體積明顯變小了。

2416f652-4197-11ed-96c9-dac502259ad0.png

另外,軟件在運(yùn)行時(shí)占用大量?jī)?nèi)存的情況也得到明顯改善。如果需要在展示實(shí)時(shí)畫面時(shí),對(duì)圖像做一些處理,也可以在 Native 層使用 OpenCV 來(lái)處理每一幀,然后將結(jié)果返回給應(yīng)用層。





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 圖像處理
    +關(guān)注

    關(guān)注

    27

    文章

    1289

    瀏覽量

    56722
  • OpenCV
    +關(guān)注

    關(guān)注

    31

    文章

    634

    瀏覽量

    41337
  • USB攝像頭
    +關(guān)注

    關(guān)注

    0

    文章

    22

    瀏覽量

    11262

原文標(biāo)題:OpenCV + Kotlin 實(shí)現(xiàn) USB 攝像頭(相機(jī))實(shí)時(shí)畫面、拍照

文章出處:【微信號(hào):CVSCHOOL,微信公眾號(hào):OpenCV學(xué)堂】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    【飛凌嵌入式OK3576-C開(kāi)發(fā)板體驗(yàn)】 USB攝像頭拍照測(cè)試

    USB攝像頭拍照USB 攝像頭插入開(kāi)發(fā)板,將自動(dòng)安裝 uvc 驅(qū)動(dòng) 使用命令查看usb
    發(fā)表于 10-10 09:24

    解決USB攝像頭所導(dǎo)致的花屏故障

    成像畫面立即恢復(fù)正常了??磥?lái)攝像頭花屏故障是由于計(jì)算機(jī)原先的USB端口損壞引起的,于是筆者又對(duì)原先的USB端口進(jìn)行了檢查,最后發(fā)現(xiàn)原先的
    發(fā)表于 03-16 09:53

    求一個(gè)用labview編寫的控制攝像頭拍照及保存的例子,謝謝!

    求一個(gè)用labview編寫的控制攝像頭拍照及保存的例子,謝謝!調(diào)用攝像頭應(yīng)該是怎么調(diào)用,然后調(diào)用
    發(fā)表于 03-15 13:05

    攝像頭用色溫鏡擋住拍照很暗

    `大家好,最近在弄一個(gè)串口攝像頭,攝像頭sensor是OV7725,DSP芯片是CL8529?,F(xiàn)在有個(gè)問(wèn)題,用藍(lán)色的色溫鏡擋住攝像頭的時(shí)候,拍照很暗,同時(shí)晚上紅外
    發(fā)表于 06-25 11:27

    android多攝像頭同時(shí)預(yù)覽

    程序可以打開(kāi),預(yù)覽畫面還算流暢,大概25幀左右。調(diào)試USB攝像頭通過(guò)UVC生成了video節(jié)點(diǎn),接著移植了camera的HAL層庫(kù)文件,可以順利打開(kāi)。當(dāng)要調(diào)用第二個(gè)
    發(fā)表于 01-18 14:55

    自制USB攝像頭程序,可拍照,可以錄制視頻

    `利用NI Vision做的USB攝像頭程序如果有多個(gè)USB攝像頭,可以從其中選擇想要用的攝像頭可以拍照
    發(fā)表于 03-14 12:17

    怎樣通過(guò)串口傳輸攝像頭畫面

    各位大神們,幫幫忙啊~~~~~怎樣通過(guò)串口顯示攝像頭畫面呢讓畫面實(shí)時(shí)顯示在labview前面板上面。。當(dāng)然 最好有個(gè)做好的小例子參考一下就最好啦
    發(fā)表于 03-08 10:25

    labview調(diào)用USB攝像頭無(wú)法選擇其它攝像頭

    labview調(diào)用USB攝像頭無(wú)法選擇其它攝像頭,選cam1但是程序采集的圖像是cam0的圖像 補(bǔ)充內(nèi)容 (2017-9-12 15:48): 把session in改變?yōu)槌A恳膊还?/div>
    發(fā)表于 09-12 10:05

    請(qǐng)問(wèn)USB攝像頭怎么在樹莓派中實(shí)現(xiàn)拍照功能?

    求助各位大神USB攝像頭怎么在樹莓派中實(shí)現(xiàn)拍照功能
    發(fā)表于 05-28 05:56

    NI vision調(diào)用筆記本攝像頭拍照做的子程序

    用NI Vision控件做的一個(gè)調(diào)用筆記本攝像頭拍照的程序
    發(fā)表于 09-30 14:37

    OV7670攝像頭模塊是如何實(shí)現(xiàn)攝像頭畫面上傳到onenet的

    OV7670攝像頭模塊是如何實(shí)現(xiàn)攝像頭畫面上傳到onenet的?
    發(fā)表于 09-30 08:53

    【賽昉科技昉·星光RISC-V單板計(jì)算機(jī)試用體驗(yàn)】使用??低?b class='flag-5'>USB攝像頭拍照和錄制視頻

    。拍照部分,我使用了camorama,可以實(shí)時(shí)預(yù)覽攝像頭畫面,并且在界面上點(diǎn)擊拍照。錄制視頻部分,可以試用的軟件很多,我選擇了使用命令行的f
    發(fā)表于 07-17 11:42

    基于LABVIEW編程的USB攝像頭拍照VI文件

    LABVIEW2018編寫的USB攝像頭攝像拍照子VI,給有需要的朋友。
    發(fā)表于 09-15 14:31 ?56次下載

    LDR6023Q給USB攝像頭帶來(lái)的神奇作用

    USB攝像頭是一款支持USB攝像頭USB視頻采集卡等USB設(shè)備通過(guò)OTG連接手機(jī)并驅(qū)動(dòng)設(shè)備
    的頭像 發(fā)表于 07-28 10:54 ?1000次閱讀
    LDR6023Q給<b class='flag-5'>USB</b><b class='flag-5'>攝像頭</b>帶來(lái)的神奇作用

    LDR6023Q是如何運(yùn)用在USB攝像頭轉(zhuǎn)接器的?

    USB攝像頭是一款支持USB攝像頭USB視頻采集卡等USB設(shè)備通過(guò)OTG連接手機(jī)并驅(qū)動(dòng)設(shè)備
    的頭像 發(fā)表于 10-21 09:52 ?673次閱讀
    LDR6023Q是如何運(yùn)用在<b class='flag-5'>USB</b><b class='flag-5'>攝像頭</b>轉(zhuǎn)接器的?
    RM新时代网站-首页