91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

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

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

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

地平線旭日X3派試用體驗(yàn) | 運(yùn)行輕量級(jí)人臉檢測模型

地瓜機(jī)器人 ? 2022-12-13 09:56 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

一、下載代碼

Linzaer的代碼倉中,提供了PyTorch和ONNX格式的預(yù)訓(xùn)練模型,同時(shí)還提供了常用框架的PythonC++推理代碼實(shí)現(xiàn),以及測試圖片、腳本和說明文檔,直接使用即可:

# 當(dāng)然,首先需要聯(lián)網(wǎng) # 如果沒有g(shù)it先安裝一下: # sudo apt install git # 下載大佬的代碼倉: git clone https://github.com/Linzaer/Ultra-Light-Fast-Generic-Face-Detector-1MB.git

下載完成后,可以通過 ls -al 命令查頂層看有哪些文件和目錄(當(dāng)然,GitHub網(wǎng)頁上也能看):

1.png

預(yù)訓(xùn)練的模型位于 models 子目錄,使用 find models/ -type f 命令,可以查看有哪些文件:

2.png

二、安裝依賴

地平線發(fā)布的旭日X3派系統(tǒng)鏡像已經(jīng)自帶了python3pip3命令,不用再安裝了。樹莓派上,如果沒有python3和pip3命令,需要先安裝:

sudo apt install python3 python3-pip

2.1 更新pip源

由于pip install 默認(rèn)會(huì)從pypi.org(國外主機(jī))下載軟件包,國內(nèi)網(wǎng)絡(luò)環(huán)境一般下載速度較慢。因此,建議修改pip源配置:

pip3 config set global.index-url http://mirrors.aliyun.com/pypi/simple/ pip3 config set global.trusted-host mirrors.aliyun.com pip3 config set global.timeout 120

2.2 按裝pip包

大佬的代碼倉中提供了requirements.txt,里面記錄執(zhí)行倉中python代碼所需的Python軟件包。使用pip命令安裝即可:

pip3 install -r requirements.txt

稍等一段時(shí)間,下載完成,如下圖:

3.png

可以看到下載鏈接已經(jīng)變成 aliyun 的了。

三、運(yùn)行模型

代碼倉頂層的 detect_imgs.py 和 detect_imgs_onnx.py 兩個(gè)腳本文件,可以直接使用 models 下的預(yù)訓(xùn)練模型進(jìn)行推理。

其中,detect_imgs.py 腳本的內(nèi)容如下:

""" This code is used to batch detect images in a folder. """ import argparse import os import sys import cv2 from vision.ssd.config.fd_config import define_img_size parser = argparse.ArgumentParser( description='detect_imgs') parser.add_argument('--net_type', default="RFB", type=str, help='The network architecture ,optional: RFB (higher precision) or slim (faster)') parser.add_argument('--input_size', default=640, type=int, help='define network input size,default optional value 128/160/320/480/640/1280') parser.add_argument('--threshold', default=0.6, type=float, help='score threshold') parser.add_argument('--candidate_size', default=1500, type=int, help='nms candidate size') parser.add_argument('--path', default="imgs", type=str, help='imgs dir') parser.add_argument('--test_device', default="cuda:0", type=str, help='cuda:0 or cpu') args = parser.parse_args() define_img_size(args.input_size) # must put define_img_size() before 'import create_mb_tiny_fd, create_mb_tiny_fd_predictor' from vision.ssd.mb_tiny_fd import create_mb_tiny_fd, create_mb_tiny_fd_predictor from vision.ssd.mb_tiny_RFB_fd import create_Mb_Tiny_RFB_fd, create_Mb_Tiny_RFB_fd_predictor result_path = "./detect_imgs_results" label_path = "./models/voc-model-labels.txt" test_device = args.test_device class_names = [name.strip() for name in open(label_path).readlines()] if args.net_type == 'slim': model_path = "models/pretrained/version-slim-320.pth" # model_path = "models/pretrained/version-slim-640.pth" net = create_mb_tiny_fd(len(class_names), is_test=True, device=test_device) predictor = create_mb_tiny_fd_predictor(net, candidate_size=args.candidate_size, device=test_device) elif args.net_type == 'RFB': model_path = "models/pretrained/version-RFB-320.pth" # model_path = "models/pretrained/version-RFB-640.pth" net = create_Mb_Tiny_RFB_fd(len(class_names), is_test=True, device=test_device) predictor = create_Mb_Tiny_RFB_fd_predictor(net, candidate_size=args.candidate_size, device=test_device) else: print("The net type is wrong!") sys.exit(1) net.load(model_path) if not os.path.exists(result_path): os.makedirs(result_path) listdir = os.listdir(args.path) sum = 0 for file_path in listdir: img_path = os.path.join(args.path, file_path) orig_image = cv2.imread(img_path) image = cv2.cvtColor(orig_image, cv2.COLOR_BGR2RGB) boxes, labels, probs = predictor.predict(image, args.candidate_size / 2, args.threshold) sum += boxes.size(0) for i in range(boxes.size(0)): box = boxes[i, :] cv2.rectangle(orig_image, (box[0], box[1]), (box[2], box[3]), (0, 0, 255), 2) # label = f"""{voc_dataset.class_names[labels[i]]}: {probs[i]:.2f}""" label = f"{probs[i]:.2f}" # cv2.putText(orig_image, label, (box[0], box[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) cv2.putText(orig_image, str(boxes.size(0)), (30, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) cv2.imwrite(os.path.join(result_path, file_path), orig_image) print(f"Found {len(probs)} faces. The output image is {result_path}") print(sum)

可以看到,該腳本中:

  • 使用 --path 選項(xiàng)執(zhí)行輸入圖片所在目錄,默認(rèn)為 imgs;
  • 將后處理后的輸出圖片保存到detect_imgs_results目錄;
  • 默認(rèn)使用models/pretrained/version-RFB-320.pth 模型。

3.1 跑torch模型

好了,準(zhǔn)備直接跑 detect_imgs.py :

4.png

失敗了,說PyTorch不是使能CUDA編譯的。

從代碼中,我們看到可以通過 test_device 選項(xiàng)指定設(shè)備,默認(rèn)是 cuda:0 。

我們手動(dòng)指定 test_device 為 CPU,繼續(xù)嘗試運(yùn)行:

5.png

又失敗了,這次是OpenCV報(bào)錯(cuò),說是 cv2.rectangle 的參數(shù)類型不對(duì)。

將box坐標(biāo)轉(zhuǎn)為int,具體修改:

diff --git a/detect_imgs.py b/detect_imgs.py index 570f6a4..73b7d38 100644 --- a/detect_imgs.py +++ b/detect_imgs.py @@ -62,7 +62,9 @@ for file_path in listdir: sum += boxes.size(0) for i in range(boxes.size(0)): box = boxes[i, :] - cv2.rectangle(orig_image, (box[0], box[1]), (box[2], box[3]), (0, 0, 255), 2) + x1, y1 = int(box[0]), int(box[1]) + x2, y2 = int(box[2]), int(box[3]) + cv2.rectangle(orig_image, (x1, y1), (x2, y2), (0, 0, 255), 2) # label = f"""{voc_dataset.class_names[labels[i]]}: {probs[i]:.2f}""" label = f"{probs[i]:.2f}" # cv2.putText(orig_image, label, (box[0], box[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)

再次執(zhí)行:

6.png

已經(jīng)可以正常識(shí)別到人臉了。

3.2 跑onnx模型

類似的,嘗試運(yùn)行 detect_imgs_onnx.py 腳本,使用onnx模型進(jìn)行推理:

7.png

這里也報(bào)錯(cuò)了。

這個(gè)報(bào)錯(cuò),我們不需要去解決它,只需要將腳本中多余的代碼刪除即可,修改內(nèi)容為:

diff --git a/detect_imgs_onnx.py b/detect_imgs_onnx.py index 2594085..9644449 100644 --- a/detect_imgs_onnx.py +++ b/detect_imgs_onnx.py @@ -8,7 +8,6 @@ import cv2 import numpy as np import onnx import vision.utils.box_utils_numpy as box_utils -from caffe2.python.onnx import backend # onnx runtime import onnxruntime as ort @@ -48,11 +47,6 @@ label_path = "models/voc-model-labels.txt" onnx_path = "models/onnx/version-RFB-320.onnx" class_names = [name.strip() for name in open(label_path).readlines()] -predictor = onnx.load(onnx_path) -onnx.checker.check_model(predictor) -onnx.helper.printable_graph(predictor.graph) -predictor = backend.prepare(predictor, device="CPU") # default CPU - ort_session = ort.InferenceSession(onnx_path) input_name = ort_session.get_inputs()[0].name result_path = "./detect_imgs_results_onnx"

四、查看結(jié)果

由于WiFi天線的問題,連接ssh,速度反應(yīng)很慢,scp拷貝文件也非常慢,一度卡住。

所以這里使用nginx Web服務(wù)器,通過HTTP協(xié)議和PC的瀏覽器查看推理輸出的結(jié)果圖片。首先安裝 nginx ,使用如下命令:

sudo apt install nginx

安裝成功后,可以通過ps命令查看nginx進(jìn)程是否正常啟動(dòng):

8.png

可以看到 nginx 進(jìn)程正常啟動(dòng)了。

查看IP地址:

9.png

將推理輸出的結(jié)果圖片拷貝到/var/www/html目錄:

10.png

我的PC此時(shí)和開發(fā)板連在同一個(gè)熱點(diǎn)上,因此,可以通過瀏覽器輸入http://192.168.0.107/9.jpg

onnx模型推理的輸出結(jié)果圖片,也可以通過同樣方法查看。

五、結(jié)果對(duì)比

本節(jié)對(duì)旭日X3派和樹莓派3B+上運(yùn)行“輕量級(jí)人臉檢測模型”的結(jié)果進(jìn)行對(duì)比。

為了方便對(duì)比,上述兩個(gè)腳本需要重新修改,最終修改為:

diff --git a/detect_imgs.py b/detect_imgs.py index 570f6a4..0886677 100644 --- a/detect_imgs.py +++ b/detect_imgs.py @@ -54,7 +54,7 @@ if not os.path.exists(result_path): os.makedirs(result_path) listdir = os.listdir(args.path) sum = 0 -for file_path in listdir: +for file_path in sorted(listdir): img_path = os.path.join(args.path, file_path) orig_image = cv2.imread(img_path) image = cv2.cvtColor(orig_image, cv2.COLOR_BGR2RGB) @@ -62,11 +62,13 @@ for file_path in listdir: sum += boxes.size(0) for i in range(boxes.size(0)): box = boxes[i, :] - cv2.rectangle(orig_image, (box[0], box[1]), (box[2], box[3]), (0, 0, 255), 2) + x1, y1 = int(box[0]), int(box[1]) + x2, y2 = int(box[2]), int(box[3]) + cv2.rectangle(orig_image, (x1, y1), (x2, y2), (0, 0, 255), 2) # label = f"""{voc_dataset.class_names[labels[i]]}: {probs[i]:.2f}""" label = f"{probs[i]:.2f}" # cv2.putText(orig_image, label, (box[0], box[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) cv2.putText(orig_image, str(boxes.size(0)), (30, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) cv2.imwrite(os.path.join(result_path, file_path), orig_image) - print(f"Found {len(probs)} faces. The output image is {result_path}") + print(f"Found {len(probs)} faces. The output image is {result_path}/{file_path}") print(sum) diff --git a/detect_imgs_onnx.py b/detect_imgs_onnx.py index 2594085..19ae9fb 100644 --- a/detect_imgs_onnx.py +++ b/detect_imgs_onnx.py @@ -8,7 +8,6 @@ import cv2 import numpy as np import onnx import vision.utils.box_utils_numpy as box_utils -from caffe2.python.onnx import backend # onnx runtime import onnxruntime as ort @@ -48,11 +47,6 @@ label_path = "models/voc-model-labels.txt" onnx_path = "models/onnx/version-RFB-320.onnx" class_names = [name.strip() for name in open(label_path).readlines()] -predictor = onnx.load(onnx_path) -onnx.checker.check_model(predictor) -onnx.helper.printable_graph(predictor.graph) -predictor = backend.prepare(predictor, device="CPU") # default CPU - ort_session = ort.InferenceSession(onnx_path) input_name = ort_session.get_inputs()[0].name result_path = "./detect_imgs_results_onnx" @@ -64,7 +58,7 @@ if not os.path.exists(result_path): os.makedirs(result_path) listdir = os.listdir(path) sum = 0 -for file_path in listdir: +for file_path in sorted(listdir): img_path = os.path.join(path, file_path) orig_image = cv2.imread(img_path) image = cv2.cvtColor(orig_image, cv2.COLOR_BGR2RGB) @@ -76,10 +70,11 @@ for file_path in listdir: image = np.expand_dims(image, axis=0) image = image.astype(np.float32) # confidences, boxes = predictor.run(image) - time_time = time.time() + start_time = time.time() confidences, boxes = ort_session.run(None, {input_name: image}) - print("cost time:{}".format(time.time() - time_time)) + stop_time = time.time() boxes, labels, probs = predict(orig_image.shape[1], orig_image.shape[0], confidences, boxes, threshold) + print(f"{file_path}, faces: {boxes.shape[0]}, time: {stop_time - start_time:.9f}") for i in range(boxes.shape[0]): box = boxes[i, :] label = f"{class_names[labels[i]]}: {probs[i]:.2f}"

添加了文件名排序、文件名輸出、推理時(shí)間輸出,方便在兩個(gè)平臺(tái)上運(yùn)行是進(jìn)行對(duì)比。

使用如下命令,進(jìn)行 torch模型數(shù)據(jù)統(tǒng)計(jì):

# 記錄運(yùn)行輸出 python3 detect_imgs.py --test_device cpu | tee torch.txt # 提取人臉數(shù) grep faces torch.txt | cut -d' ' -f2 # 提取消耗時(shí)間 grep time: torch.txt | awk '{print $3}'

經(jīng)上述命令統(tǒng)計(jì),torch模型在旭日X3派和樹莓派3B+的運(yùn)行結(jié)果如下:

12.png

可以看到,旭日X3派上torch模型平均耗時(shí)要比樹莓派短58%,而這僅僅只是CPU計(jì)算性能差異。

類似的,兩個(gè)開發(fā)板運(yùn)行onnx模型的結(jié)果如下:

13.png

可以看到,旭日X3派上onnx模型平均耗時(shí)要比樹莓派短53%,而這僅僅只是CPU計(jì)算性能差異。

原作者:xusiwei1236
原鏈接:詳見地平線開發(fā)者社區(qū)

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

    關(guān)注

    5200

    文章

    20476

    瀏覽量

    334480
  • 人工智能
    +關(guān)注

    關(guān)注

    1818

    文章

    50120

    瀏覽量

    265612
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    地平線正式開源HoloBrain VLA基座模型

    2月13日,地平線正式宣布其HoloBrain-0基座模型及框架全面開源。本次開源不僅包括HoloBrain-0核心算法,地平線同步開放完整基礎(chǔ)設(shè)施RoboOrchard。作為地平線機(jī)
    的頭像 發(fā)表于 02-26 10:05 ?333次閱讀
    <b class='flag-5'>地平線</b>正式開源HoloBrain VLA基座<b class='flag-5'>模型</b>

    地平線與行深智能達(dá)成戰(zhàn)略合作

    12月9日,在“向高 同行丨2025地平線技術(shù)生態(tài)大會(huì)”上,地平線與無人駕駛技術(shù)與智慧物流產(chǎn)品提供商行深智能正式簽署戰(zhàn)略合作協(xié)議,行深智能將基于地平線征程6P打造L4級(jí)物流場景自動(dòng)駕駛方案,并計(jì)劃于2026年6月啟動(dòng)量產(chǎn)部署,為
    的頭像 發(fā)表于 12-16 16:18 ?1274次閱讀

    地平線與元戎啟行達(dá)成戰(zhàn)略合作

    在市場需求與技術(shù)演進(jìn)的共同驅(qū)動(dòng)下,高階輔助駕駛的規(guī)?;占耙巡饺腙P(guān)鍵窗口期。12月9日,在“向高 同行丨2025地平線技術(shù)生態(tài)大會(huì)”上,地平線與國際領(lǐng)先的人工智能企業(yè)元戎啟行達(dá)成合作,雙方將
    的頭像 發(fā)表于 12-16 16:08 ?357次閱讀

    構(gòu)建生態(tài)新范式!開源大腦+小腦,地平線發(fā)布兩款具身智能模型

    在2025地平線技術(shù)生態(tài)大會(huì)上,地平線創(chuàng)始人兼CEO余凱正式發(fā)布兩大具身智能開源模型——具身智能小腦基座模型HoloMotion和具身智能大腦基座
    的頭像 發(fā)表于 12-16 15:01 ?1.2w次閱讀
    構(gòu)建生態(tài)新范式!開源大腦+小腦,<b class='flag-5'>地平線</b>發(fā)布兩款具身智能<b class='flag-5'>模型</b>

    知行科技亮相2025地平線技術(shù)生態(tài)大會(huì)

    12月8日、9日,知行科技作為地平線征程6BEM系列芯片軟硬件合作伙伴亮相地平線技術(shù)生態(tài)大會(huì),并展出了基于征程6BEM系列芯片打造的組合輔助駕駛解決方案,覆蓋主動(dòng)安全到高階領(lǐng)航功能;同時(shí),知行科技iRC100P具身AI BOX也亮相大會(huì),成為知行科技與
    的頭像 發(fā)表于 12-12 12:50 ?1382次閱讀

    地平線HSD量產(chǎn)先鋒品鑒會(huì)圓滿落幕

    2025年11月19日-24日,地平線在廣州舉辦Drive on Horizon·HSD量產(chǎn)先鋒品鑒會(huì)。首搭地平線HSD及征程6P的星途ET5、搭載征程6的深藍(lán)L06開啟輔助駕駛體驗(yàn),以出色的實(shí)際
    的頭像 發(fā)表于 11-27 11:27 ?461次閱讀

    地平線助力博世中階智能輔助駕駛方案量產(chǎn)交付

    2025年4月,地平線與博世深化戰(zhàn)略合作,雙方基于征程6系列加速智能輔助駕駛方案的研發(fā)與應(yīng)用。近日,搭載征程6M的博世中階智能輔助駕駛方案的全新量產(chǎn)合作車型東風(fēng)奕eπ007+、北京越野BJ40增程元境智行版先后上市,標(biāo)志著地平線
    的頭像 發(fā)表于 11-19 11:47 ?585次閱讀

    地平線與Unity中國達(dá)成戰(zhàn)略合作

    近日,中國智駕科技領(lǐng)軍企業(yè)地平線與全球領(lǐng)先的實(shí)時(shí)3D內(nèi)容創(chuàng)作和運(yùn)營平臺(tái)Unity正式簽署戰(zhàn)略合作協(xié)議。雙方將深度融合地平線HSD (Horizon SuperDrive) 人機(jī)交互系統(tǒng)與Unity
    的頭像 發(fā)表于 11-03 16:43 ?1570次閱讀

    地平線與哈啰正式簽署戰(zhàn)略合作協(xié)議

    9月11日,在2025Inclusion·外灘大會(huì)上,地平線與哈啰正式簽署戰(zhàn)略合作協(xié)議。雙方將基于Robotaxi運(yùn)營場景和需求,發(fā)揮各自技術(shù)優(yōu)勢,共同打造極致低成本、高安全、高可靠、高可用的智能
    的頭像 發(fā)表于 09-12 14:25 ?937次閱讀

    基于米爾瑞芯微RK3576開發(fā)板部署運(yùn)行TinyMaix:超輕量級(jí)推理框架

    推理庫,可以讓你在任意低資源MCU上運(yùn)行輕量級(jí)深度學(xué)習(xí)模型。關(guān)鍵特性核心代碼少于 400行(tm_layers.c+tm_model.c+arch_cpu.h), 代碼段(.text)少于3
    發(fā)表于 07-25 16:35

    Arm攜手地平線推動(dòng)汽車智能化變革

    近日,地平線在上海舉辦了 2025 年度產(chǎn)品發(fā)布會(huì),推出了 L2 城區(qū)輔助駕駛系統(tǒng)——地平線 HSD,不僅集中展示了自身領(lǐng)先的技術(shù)實(shí)力,更深刻詮釋了汽車智能化加速普及的產(chǎn)業(yè)發(fā)展趨勢,成為上海車展的前哨。地平線征程 6P 作為技術(shù)
    的頭像 發(fā)表于 04-28 14:28 ?1263次閱讀

    地平線與博世達(dá)成戰(zhàn)略合作

    近日,地平線正式宣布與全球領(lǐng)先的汽車技術(shù)與服務(wù)供應(yīng)商博世達(dá)成戰(zhàn)略合作。根據(jù)協(xié)議,博世將基于地平線征程6B打造新一代多功能攝像頭,并基于征程6E/M打造博世縱橫輔助駕駛升級(jí)版。目前,基于征程6系列開發(fā)的博世新一代多功能攝像頭與博世縱橫輔助駕駛升級(jí)版均獲得多家車企的項(xiàng)目定點(diǎn)。
    的頭像 發(fā)表于 04-27 13:43 ?1225次閱讀

    地平線城區(qū)輔助駕駛系統(tǒng)HSD解讀

    近日,在2025地平線年度產(chǎn)品發(fā)布會(huì)上,地平線城區(qū)輔助駕駛系統(tǒng)HSD正式發(fā)布。作為國內(nèi)首個(gè)軟硬結(jié)合全棧開發(fā)的城區(qū)輔助駕駛系統(tǒng),地平線HSD搭載當(dāng)前最高性能的國產(chǎn)智駕計(jì)算方案征程6P,采用一段式端到端
    的頭像 發(fā)表于 04-22 14:44 ?2315次閱讀

    地平線推出L2城區(qū)輔助駕駛系統(tǒng)HSD

    近日,以“征程所向,遠(yuǎn)超想象”為主題的2025地平線年度產(chǎn)品發(fā)布會(huì)在上海滴水湖舉行。地平線重磅推出L2城區(qū)輔助駕駛系統(tǒng)——地平線HSD,構(gòu)建體驗(yàn)“類人”、用戶“信任”的城區(qū)輔助駕駛新解。同時(shí),
    的頭像 發(fā)表于 04-19 09:14 ?1058次閱讀

    地平線與上汽集團(tuán)深化戰(zhàn)略合作

    近日,上汽集團(tuán)舉辦“懂車更懂你·2025上汽之夜”活動(dòng),地平線創(chuàng)始人兼CEO余凱博士受邀發(fā)表主旨演講。作為地平線第一大機(jī)構(gòu)股東,上汽集團(tuán)在發(fā)布會(huì)上表示將繼續(xù)拓展與地平線等頭部企業(yè)的合作,借助各自領(lǐng)域的優(yōu)勢資源互補(bǔ),打造擁有全新體
    的頭像 發(fā)表于 04-12 09:07 ?1119次閱讀