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

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

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

aikit 2023 3D與機械臂結(jié)合!

大象機器人科技 ? 來源:大象機器人科技 ? 作者:大象機器人科技 ? 2023-11-28 10:38 ? 次閱讀

引言
今天我們主要了解3D攝像頭是如何跟機械臂應(yīng)用相結(jié)合的。我們最近準備推出一款新的機械臂套裝AI Kit 2023 3D,熟悉我們的老用戶應(yīng)該知道,我們之前的AI Kit 2023套裝使用的是2D攝像頭。

隨著技術(shù)進步,市場需求和領(lǐng)域的擴大,2D的攝像頭已經(jīng)不能夠滿足很多場景。3D攝像頭也在近些年間火了起來。隨著我們的步伐,一起來認識一下3D攝像頭帶給我們的應(yīng)用。

產(chǎn)品介紹
RealSence-Depth camera

wKgaomVlUCiACldUAAOqB_t8238205.png


我們今天涉及到的3D攝像頭是RealSence是Intel公司開發(fā)的一種深度感知攝像頭??梢詮膱D片中看出來,這個相機有四個鏡頭,它們分別是一個紅外激光投影儀,兩個紅外攝像頭和一個彩色攝像頭。這幾個鏡頭具體有啥作用:

紅外激光投影儀:

投射一個紅外光點網(wǎng)格到場景中,然后這些光點被紅外攝像頭捕獲。因為投影儀和攝像頭的位置是固定的,所以通過計算光點在攝像頭中的位置偏移,可以推算出每個光點對應(yīng)的物體距離攝像頭的距離,從而得到場景的深度信息。

紅外攝像頭:

紅外攝像頭是一種能夠捕獲紅外光譜的攝像頭。紅外光譜是電磁譜中的一部分,其波長長于可見光,但短于微波。紅外攝像頭的主要作用是能夠在無可見光照明的條件下進行成像,因為許多物體會發(fā)射、反射或透過紅外光。

彩色攝像頭:

通常用于捕獲場景的常規(guī)視覺信息,而其他的攝像頭則用于捕獲額外的信息,如場景的深度信息或在低光照條件下的圖像。這些信息可以與彩色攝像頭捕獲的圖像相結(jié)合,以提供更豐富的視覺數(shù)據(jù),支持更高級的功能,如面部識別、增強現(xiàn)實或3D建模等。

結(jié)合這四個攝像頭的功能,能夠獲取一個物體的三維信息,這種技術(shù)可以用于人臉識別、手勢識別、物體識別、測量物體的深度等多種應(yīng)用。

wKgaomVlUDyAe_Q4AAkCHRp2jk4869.png

Artificial Intelligence Kit 3D

wKgaomVlUFGAGRksADP_22V8mh0667.png


人工智能3D套裝是機械臂應(yīng)用人工智能,機器視覺的入門款套裝。套裝使用了四種識別算法,顏色識別,形狀識別,yolov8等,適配可視化的操作界面,使用3D攝像頭解決了2D攝像頭需要標志定位的短板,開源代碼基于python平臺,可通過開發(fā)軟件實現(xiàn)機械臂的控制。

該套裝是搭配機械臂(myCobot,mechArm,myArm)進行使用,仿工業(yè)場景的構(gòu)造。

wKgZomVlUGKAKg2vACJNfHp046c094.pngwKgaomVlUG6AQfBWAAPcAiUuE34571.png

myCobot 280
myCobot 280 M5是一款由Elephant Robotics和M5Stack聯(lián)合開發(fā)的最小和最輕的六軸協(xié)作機器人。它采用集成模塊化設(shè)計,重量僅為850克,非常輕巧,搭載6個高性能伺服電機,具有快速響應(yīng),慣性小和平滑旋轉(zhuǎn)的特點。

wKgaomVlUHyADM83AAV3vnjgyZY410.png

3D攝像頭應(yīng)用領(lǐng)域
如果在同一個應(yīng)用領(lǐng)域中,用2D攝像頭和3D攝像頭它們的表型性能會怎樣。從我們身邊常見的來了解:

wKgaomVlUOOAWsq5AAEw6eRTyn8570.png

從圖標中可以知道,2D攝像頭需要通過特定的算法來得到一些參數(shù),而3D攝像頭能夠直接獲取較多的信息,在同一應(yīng)用領(lǐng)域下的性能更加精準。在未來的,3D攝像頭的趨勢必然是飛速增長的!

這也是我們推出3D人工智能套裝的原因之一,跟上時代的步伐。

算法介紹
機械臂視覺識別,一定會涉及手眼標定。雖然兩種版本的手眼標定的流程是一樣的,但是他們在計算中還是會有一些差別,我們先看它們的識別區(qū)。

wKgaomVlUPGAWf4gAAZvBhVUCFo566.png

從中間的是被區(qū)域可以看到,3D版本已經(jīng)沒有了二維碼的標識,在2D版本上二維碼的標識的主要功能是確定識別的區(qū)域,以及提供一個固定高度的值。在獲取了三維數(shù)據(jù)之后,就不需要用到二維碼進行標識了,可以直接獲取到相機距離平面高度的值。

這一點體現(xiàn)了3D攝像頭能夠直接獲取深度的信息。

如何使用 realsence 在python中
environment build
operate system:window10/11
program language:python 3.9+
libraries:
from typing import Tuple, Optional
import pyrealsense2 as rs
import numpy as np
import cv2
import time


class RealSenseCamera:
   def __init__(self):
       super().__init__()

       # Configure depth and color streams
       self.pipeline = rs.pipeline()
       self.config = rs.config()
       self.config.enable_stream(rs.stream.color, 1920, 1080, rs.format.bgr8, 30)
       # Is the camera mirror image reversed
       self.flip_h = False
       self.flip_v = False

       # Get device product line for setting a supporting resolution
       pipeline_wrapper = rs.pipeline_wrapper(self.pipeline)
       pipeline_profile = self.config.resolve(pipeline_wrapper)
       # set auto exposure
       color = pipeline_profile.get_device().query_sensors()[0]
       color.set_option(rs.option.enable_auto_exposure, True)

       device = pipeline_profile.get_device()

       sensor_infos = list(
           map(lambda x: x.get_info(rs.camera_info.name), device.sensors)
       )

       # set resolution
       self.config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
       self.config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)

       align_to = rs.stream.color
       self.align = rs.align(align_to)

   def capture(self):
       # Start streaming
       self.pipeline.start(self.config)

       # warm up
       for i in range(60):
           pipeline = self.pipeline
           frames = pipeline.wait_for_frames()

   def release(self):
       self.pipeline.stop()

   def update_frame(self) -> None:
       pipeline = self.pipeline
       frames = pipeline.wait_for_frames()
       aligned_frames = self.align.process(frames)
       self.curr_frame = aligned_frames
       self.curr_frame_time = time.time_ns()

   def color_frame(self) -> Optional[np.ndarray]:
       frame = self.curr_frame.get_color_frame()
       if not frame:
           return None
       frame = np.asanyarray(frame.get_data())
       if self.flip_h:
           frame = cv2.flip(frame, 1)
       if self.flip_v:
           frame = cv2.flip(frame, 0)
       return frame

   def depth_frame(self) -> Optional[np.ndarray]:
       frame = self.curr_frame.get_depth_frame()
       if not frame:
           return None
       frame = np.asanyarray(frame.get_data())
       if self.flip_h:
           frame = cv2.flip(frame, 1)
       if self.flip_v:
           frame = cv2.flip(frame, 0)
       return frame

顏色識別和形狀識別都是基于openCV提供的算法來識別物體抓取物體。只需要簡單的做一個hsv的檢測的算法就能夠檢測出來顏色。
# 初始化要識別的顏色
   def __init__(self) -> None:
       self.area_low_threshold = 15000
       self.detected_name = None
       self.hsv_range = {
           "green": ((40, 50, 50), (90, 256, 256)),
           # "blueA": ((91, 100, 100), (105, 256, 256)),
           # "yellow": ((20, 240, 170), (30, 256, 256)),
           "yellow": ((15, 46, 43), (30, 256, 256)),
           "redA": ((0, 100, 100), (6, 256, 256)),
           "redB": ((170, 100, 100), (179, 256, 256)),
           # "orange": ((8, 100, 100), (15, 256, 256)),
           "blue": ((100, 43, 46), (124, 256, 256)),
       }
       
# 對圖像的處理
result = []
       for color, (hsv_low, hsv_high) in self.hsv_range.items():
           hsv_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
           in_range = cv2.inRange(hsv_frame, hsv_low, hsv_high)

           # 對顏色區(qū)域進行膨脹和腐蝕
           kernel = np.ones((5, 5), np.uint8)
           in_range = cv2.morphologyEx(in_range, cv2.MORPH_CLOSE, kernel)
           in_range = cv2.morphologyEx(in_range, cv2.MORPH_OPEN, kernel)

           contours, hierarchy = cv2.findContours(
               in_range, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
           )

           contours = list(
               filter(lambda x: cv2.contourArea(x) > self.area_low_threshold, contours)
           )

           rects = list(map(cv2.minAreaRect, contours))
           boxes = list(map(cv2.boxPoints, rects))
           boxes = list(map(np.int32, boxes))

           if len(boxes) != 0:
               if color.startswith("red"):
                   color = "red"
               for box in boxes:
                   result.append(ColorDetector.DetectResult(color, box))
                   # self.detected_name = result
                   self.detected_name = result[0].color
       return result


YOLOv8 和拆碼垛
我們在這個套裝里面還使用到了目前比較火的一款識別模型YOLOv8,此模型還涉及到深度學(xué)習(xí)和模型訓(xùn)練等功能。

YOLOv8是一種目標檢測算法,它是基于深度學(xué)習(xí)的YOLO(You Only Look Once)系列算法的最新版本。YOLO算法是一種實時目標檢測算法,其特點是能夠在一次前向傳播中同時完成目標檢測和定位,速度非???。Home - Ultralytics YOLOv8 Docs

主要特點:

高性能:YOLOv8在目標檢測任務(wù)中具有較高的準確性和速度。它能夠在實時或接近實時的速度下進行目標檢測,適用于各種應(yīng)用場景。
簡單而有效的設(shè)計:YOLOv8采用了簡單而有效的設(shè)計,通過使用更深的網(wǎng)絡(luò)結(jié)構(gòu)和更多的特征層來提高檢測性能。它還使用了一種自適應(yīng)的訓(xùn)練策略,可以在不同的目標檢測任務(wù)上進行快速訓(xùn)練和調(diào)整。
多種規(guī)模的檢測:YOLOv8提供了不同的模型大小,包括小型、中型和大型模型,以滿足不同場景下的需求。這些模型可以在不同的硬件設(shè)備上進行部署和使用。
開源和易用性:YOLOv8是開源的,代碼和預(yù)訓(xùn)練模型都可以在GitHub上獲得。它還提供了簡單易用的API,使得用戶可以方便地進行模型訓(xùn)練、推理和部署。
要使用YOLOv8是需要進行自定義訓(xùn)練模型的,在進行目標檢測任務(wù)是,根據(jù)具體應(yīng)用場景和需求,通過在自定義數(shù)據(jù)集上進行訓(xùn)練得到模型。

為什么要訓(xùn)練模型呢?訓(xùn)練模型的目的是讓計算機能夠自動識別和定位圖像或視頻中的目標物體。通過訓(xùn)練模型,我們可以讓計算機學(xué)會如何識別不同種類的物體,并且能夠準確地定位它們的位置。這對于許多應(yīng)用場景非常重要,比如自動駕駛、安防監(jiān)控、智能交通等。

對此我們的源碼文件中已經(jīng)包含了我們自己訓(xùn)練的模型,如果你對YOLOv8的技術(shù)很熟練了,你可以自己對識別物體進行訓(xùn)練。

下面的代碼是程序中使用的代碼

class YOLODetector:
   DetectResult = List[ultralytics.engine.results.Results]

   def __init__(self) -> None:
       """
       init YOLO model。
       """
       self.model_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + '/resources/yolo/best.pt'
       self.model = YOLO(self.model_path)
       self.predict_args = {"conf": 0.2}

       self.detected_name = None

   def get_radian(self, res: DetectResult):
       return 0

   def detect(self, frame: np.ndarray):
       """
       Perform object detection on input images.
       Args:
           frame (np.ndarray): Input image frame.
       Returns:
           List[DetectResult]: A list containing the detection results.
       """
       res = self.model.predict(frame, **self.predict_args)
       res = list(filter(lambda x: len(x.boxes) != 0, res))
       if len(res) == 0:
           return None
       else:
           names = self.get_names(res)
           self.detected_name = names
           return res

   def draw_result(self, frame: np.ndarray, res: List[DetectResult]):
       """
       Draws the bounding box of the detection results on the image.
       Args:
            frame (np.ndarray): Input image frame.
            res (List[DetectResult]): List of detection results.
       """
       res = list(filter(lambda x: len(x.boxes) != 0, res))
       for r in res:
           boxes = r.boxes.xyxy.numpy()
           for box in boxes:
               x1, y1, x2, y2 = box.astype(int)
               cv2.rectangle(frame, (x1, y1), (x2, y2), color=(0, 255, 0), thickness=1)
               cv2.putText(frame, "Name: " + str(self.detected_name), (20, 80),
                           cv2.FONT_HERSHEY_COMPLEX_SMALL, 1,
                           (0, 0, 255))
           # x1, y1, x2, y2 = np.squeeze(r.boxes.xyxy.numpy()).astype(int)
           # cv2.rectangle(frame, (x1, y1), (x2, y2), color=(0, 255, 0), thickness=1)

   def target_position(self, res: DetectResult) -> Tuple[int, int]:
       """
       Extract the location information of the target from the detection results.
        Args:
            res (DetectResult): detection result.
        Returns:
            Tuple[int, int]: The position coordinates (x, y) of the target.
       """
       boxes = res.boxes.xywh.numpy()
       boxs_list = []
       for box in boxes:
           x, y, w, h = box.astype(int)
           boxs_list.append((x, y))
       boxs_list = tuple(boxs_list)
       return boxs_list

   def get_rect(self, res: DetectResult):
       """
       Obtain the bounding box coordinate information of the target from the detection result.
       Args:
            res (DetectResult): detection result.
        Returns:
            List[Tuple[int, int]]: The bounding box coordinate information of the target, including four vertex coordinates.
       """
       boxes = res.boxes.xywh.numpy()
       box_list = []
       for box in boxes:
           x, y, w, h = box.astype(int)
           size = 3
           rect = [
               [x - size, y - size],
               [x + size, y - size],
               [x + size, y + size],
               [x - size, y + size],
           ]
           box_list.append(rect)
       return box_list

   def get_names(self, res: DetectResult):
       """
       Get the category name in the detection results
       Args:
            res (DetectResult): detection result.
        Returns:
            List[names]: A list category names.
       """
       names_dict = {
           0: 'jeep', 1: 'apple', 2: 'banana1', 3: 'bed', 4: 'grape',
           5: 'laptop', 6: 'microwave', 7: 'orange', 8: 'pear',
           9: 'refrigerator1', 10: 'refrigerator2', 11: 'sofa', 12: 'sofa2',
           13: 'tv', 14: 'washing machine1'
       }

       ids = [int(cls) for cls in res[0].boxes.cls.numpy()]  # Assuming you have only one result in the list
       names = [names_dict.get(id, 'Unknown') for id in ids]

       return names
wKgaomVlUjiAGHlfAARerGQ7tto751.png

搭配上3D攝像頭的特性,獲取被識別的物體的高度實現(xiàn)拆碼垛的demo,能夠?qū)⑺麄兿癫鸱e木一樣拆除。

wKgaomVlUmaAKyRaAGSg6OjKUd4855.png

總結(jié)
我們的機械臂和深度攝像頭套裝不僅是一款產(chǎn)品,更是一個開啟學(xué)習(xí)之門的機會。這個套裝以用戶友好的方式,提供了一個理想的平臺,讓初學(xué)者可以在實踐中探索和學(xué)習(xí)機械臂操作和機器視覺的知識,更重要的是,它提供了一個獨特的機會,讓用戶能夠深入理解和掌握3D相機算法。

隨著科技的進步,3D攝像頭的應(yīng)用正在迅速擴展到多個領(lǐng)域,包括但不限于制造、安全、娛樂和醫(yī)療。我們堅信,通過使用我們的套裝,用戶將能夠把握這一技術(shù)趨勢,為自己的未來學(xué)習(xí)和職業(yè)生涯奠定堅實的基礎(chǔ)。


審核編輯 黃宇

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

    關(guān)注

    213

    文章

    29498

    瀏覽量

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

    關(guān)注

    1804

    文章

    48716

    瀏覽量

    246523
  • 開源
    +關(guān)注

    關(guān)注

    3

    文章

    3611

    瀏覽量

    43485
  • 機械臂
    +關(guān)注

    關(guān)注

    13

    文章

    544

    瀏覽量

    25222
  • 大象機器人
    +關(guān)注

    關(guān)注

    0

    文章

    85

    瀏覽量

    71
收藏 人收藏

    評論

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

    3D AD庫文件

    3D庫文件
    發(fā)表于 05-28 13:57 ?3次下載

    3D閃存的制造工藝與挑戰(zhàn)

    3D閃存有著更大容量、更低成本和更高性能的優(yōu)勢,本文介紹了3D閃存的制造工藝與挑戰(zhàn)。
    的頭像 發(fā)表于 04-08 14:38 ?676次閱讀
    <b class='flag-5'>3D</b>閃存的制造工藝與挑戰(zhàn)

    3D IC背后的驅(qū)動因素有哪些?

    3D多芯片設(shè)計背后的驅(qū)動因素以及3D封裝的關(guān)鍵芯片到芯片和接口IP要求。3D多芯片設(shè)計的市場預(yù)測顯示,硅片的設(shè)計和交付方式將發(fā)生前所未有的變化。IDTechEx預(yù)測到2028年Chiplet市場規(guī)模
    的頭像 發(fā)表于 03-04 14:34 ?403次閱讀
    <b class='flag-5'>3D</b> IC背后的驅(qū)動因素有哪些?

    SciChart 3D for WPF圖表庫

    SciChart 3D for WPF 是一個實時、高性能的 WPF 3D 圖表庫,專為金融、醫(yī)療和科學(xué)應(yīng)用程序而設(shè)計。非常適合需要極致性能和豐富的交互式 3D 圖表的項目。 使用我們
    的頭像 發(fā)表于 01-23 13:49 ?482次閱讀
    SciChart <b class='flag-5'>3D</b> for WPF圖表庫

    騰訊混元3D AI創(chuàng)作引擎正式發(fā)布

    近日,騰訊公司宣布其自主研發(fā)的混元3D AI創(chuàng)作引擎已正式上線。這一創(chuàng)新性的創(chuàng)作工具將為用戶帶來前所未有的3D內(nèi)容創(chuàng)作體驗,標志著騰訊在AI技術(shù)領(lǐng)域的又一重大突破。 混元3D AI創(chuàng)作引擎憑借其強大
    的頭像 發(fā)表于 01-23 10:33 ?508次閱讀

    騰訊混元3D AI創(chuàng)作引擎正式上線

    近日,騰訊公司宣布其自主研發(fā)的混元3D AI創(chuàng)作引擎已正式上線。這一創(chuàng)新性的創(chuàng)作工具,標志著騰訊在3D內(nèi)容生成領(lǐng)域邁出了重要一步。 混元3D AI創(chuàng)作引擎的核心功能極為強大,用戶只需通過簡單的提示詞
    的頭像 發(fā)表于 01-22 10:26 ?486次閱讀

    使用myCobot 280機械結(jié)合ROS2系統(tǒng)搭建機械分揀站

    這篇文章是來自Automatic Addison的開源項目,已獲作者授權(quán)轉(zhuǎn)載自github。本項目的主要內(nèi)容是使用myCobot 280機械結(jié)合ROS2系統(tǒng)搭建機械分揀站。
    的頭像 發(fā)表于 01-15 09:22 ?619次閱讀
    使用myCobot 280<b class='flag-5'>機械</b><b class='flag-5'>臂</b><b class='flag-5'>結(jié)合</b>ROS2系統(tǒng)搭建<b class='flag-5'>機械</b>分揀站

    FPC與3D打印技術(shù)的結(jié)合 FPC在汽車電子中的應(yīng)用前景

    隨著科技的不斷進步,柔性印刷電路板(FPC)和3D打印技術(shù)在汽車電子領(lǐng)域的應(yīng)用日益廣泛。 一、FPC與3D打印技術(shù)的結(jié)合 FPC技術(shù)簡介 柔性印刷電路板(FPC)是一種具有高度靈活性和可彎曲性
    的頭像 發(fā)表于 12-03 10:23 ?953次閱讀

    3D霍爾效應(yīng)傳感器在機器人設(shè)計中的機械優(yōu)勢

    電子發(fā)燒友網(wǎng)站提供《3D霍爾效應(yīng)傳感器在機器人設(shè)計中的機械優(yōu)勢.pdf》資料免費下載
    發(fā)表于 09-03 11:36 ?0次下載
    <b class='flag-5'>3D</b>霍爾效應(yīng)傳感器在機器人設(shè)計中的<b class='flag-5'>機械</b>優(yōu)勢

    奧比中光推出2.0版大模型機械

    香薰、播放音樂等一系列復(fù)雜任務(wù)。此前在2023年底,奧比中光成功發(fā)布大模型機械1.0,在業(yè)界引起廣泛關(guān)注。
    的頭像 發(fā)表于 07-19 16:50 ?1098次閱讀

    歡創(chuàng)播報 騰訊元寶首發(fā)3D生成應(yīng)用

    App。 騰訊元寶APP發(fā)布時,就圍繞工作效率場景、日常生活等場景提供了豐富的應(yīng)用,并有創(chuàng)建個人智能體等個性化體驗,“3D角色夢工廠”則將大模型生成技術(shù)和3D應(yīng)用結(jié)合,進一步創(chuàng)新了元寶的獨特玩法。通過“
    的頭像 發(fā)表于 07-18 11:39 ?1144次閱讀
    歡創(chuàng)播報 騰訊元寶首發(fā)<b class='flag-5'>3D</b>生成應(yīng)用

    裸眼3D筆記本電腦——先進的光場裸眼3D技術(shù)

    隨著科技的不斷進步,裸眼3D技術(shù)已經(jīng)不再是科幻電影中的幻想。如今,英倫科技裸眼3D筆記本電腦將這一前沿科技帶到了我們的日常生活中。無論你是專業(yè)的3D模型設(shè)計師,還是希望在視頻播放和模型展示中體驗逼真
    的頭像 發(fā)表于 07-16 10:04 ?945次閱讀

    大象機器人開源協(xié)作機械機械接入GPT4o大模型!

    本文已經(jīng)或者同濟子豪兄作者授權(quán)對文章進行編輯和轉(zhuǎn)載 引言 隨著人工智能和機器人技術(shù)的快速發(fā)展,機械在工業(yè)、醫(yī)療和服務(wù)業(yè)等領(lǐng)域的應(yīng)用越來越廣泛。通過結(jié)合大模型和多模態(tài)AI,機械
    的頭像 發(fā)表于 07-03 14:09 ?1466次閱讀
    大象機器人開源協(xié)作<b class='flag-5'>機械</b><b class='flag-5'>臂</b><b class='flag-5'>機械</b><b class='flag-5'>臂</b>接入GPT4o大模型!

    電子發(fā)燒友

    中國電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會員交流學(xué)習(xí)
    • 獲取您個性化的科技前沿技術(shù)信息
    • 參加活動獲取豐厚的禮品