Lorsque vous utilisez le module de caméra Raspeye, vous pouvez rencontrer des phénomènes tels que le rétrécissement de l'angle de vue ou la modification de la qualité de l'image lors de la prise de vue à une résolution spécifique. C'est un phénomène causé par la différence de sensor_mode.
sensor_mode est un paramètre qui spécifie comment utiliser le capteur d'image. Par exemple, vous pouvez utiliser uniquement certains des pixels du capteur ou traiter 4 pixels comme 1 pixel. Le fonctionnement de chaque mode est préparé sous forme de tableau de correspondance pour chaque module de caméra.
Ici, comme exemple de lecture du tableau, le tableau du module v2 est cité.
C'est le mode capteur. Le module v2 peut être spécifié de 1 à 7. 2 et 3 sont exactement les mêmes, mais cela semble être le résultat de la compatibilité avec le module v1.
Resolution La résolution de l'image à capturer. Si vous spécifiez une valeur autre que la valeur décrite ici, un redimensionnement se produira.
Aspect Ratio Le rapport hauteur / largeur de l'image.
Framerates C'est la fréquence d'images qui peut être définie.
Video[1] Indique le mode du capteur qui peut être défini lors de l'utilisation du port vidéo (le signe x dans le tableau signifie ✓ [^ check]). Il prend en charge de 1 à 7. Le port vidéo peut être utilisé en réglant ʻuse_video_port = True` lors de l'enregistrement d'une vidéo ou d'une image fixe. Il est plus rapide que le port fixe, mais il a tendance à donner une image granuleuse.
Image[2] Il s'agit d'un mode de capteur qui peut être défini lors de l'utilisation du port fixe (image fixe). Le port fixe est pris à la résolution maximale, et lorsque la résolution est spécifiée, il est redimensionné à cette taille. Une suppression puissante du bruit peut être utilisée, mais elle est plus lente.
FoV (Field of View) Quelle zone du capteur utiliser. Si Plein, la zone entière du capteur est utilisée, et si Partiel, une partie est utilisée. Par conséquent, l'angle de vue (FoV) est plus étroit pour ceux qui sont partiels.
Binning S'il faut effectuer un binning de pixels. Aucun ne traite la même taille de pixel (point par point), et 2x2 traite 4 pixels comme 1 pixel. En plus d'abaisser la résolution, le binning des pixels a également pour effet de réduire le bruit.
Vous trouverez ci-dessous un diagramme du sensor_mode et de la plage de prise de vue. À partir du tableau ci-dessus et de la figure ci-dessous, vous pouvez voir que sensor_mode = 2 ou 3 ou 4 doit être utilisé pour tirer à l'angle maximum en utilisant l'ensemble du capteur. Vous pouvez également voir que l'angle de vue devient plus étroit si vous le définissez sur un autre sensor_mode ou résolution (par exemple, 1920x1080).
Comme cela sera décrit plus loin, si sensor_mode n'est pas spécifié, Resolution et Framerate sélectionneront automatiquement sensor_mode.
Les tableaux et images présentés ici sont tirés de la documentation picamera ci-dessous. https://picamera.readthedocs.io/en/release-1.13/fov.html
[^ check]: outre-mer, la marque x est utilisée pour signifier un chèque. https://www.sociomedia.co.jp/7304
C'est un flux de binning 2x2. ①: disposition des couleurs du capteur (disposition Bayer) ②: prenez la moyenne de 4 pixels pour chaque couleur (g1 et g2 sont distingués) ③: après avoir pris la moyenne
Étant donné que la moyenne des pixels est prise de cette manière, elle a un effet de réduction du bruit. Cela a également pour effet d'accélérer la prise de vue car le nombre de pixels peut être réduit avant que le traitement de l'image (démosaïque, réglage de la balance des blancs, etc.) ne soit effectué.
Si vous souhaitez en savoir plus sur le capteur, veuillez consulter la fiche technique. IMX219 (module v2) a un binning écrit à la p.53 de la fiche technique. Fiche technique IMX219 (module v2): https://www.raspberrypi.org/forums/viewtopic.php?t=177308
picamera est actuellement (2020/10) et n'a pas été mis à jour depuis plus de 2 ans. Pour cette raison, certaines parties sont différentes du site Raspberry Pi OS (raspbian). Par conséquent, nous citons ici deux tableaux, le tableau de documentation picamera et le tableau du système d'exploitation Raspberry Pi.
Source du devis: picamera document:https://picamera.readthedocs.io/en/release-1.13/fov.html Raspberry Pi OS document: https://www.raspberrypi.org/documentation/raspbian/applications/camera.md
v1 (OV5647) picamera document
Raspberry Pi OS document
C'est presque la même chose sauf pour la partie binning. Je pense que 4x4binning et 2x2 + skip ont des significations différentes, mais qu'en est-il?
v2 (IMX219)
picamera document
Raspberry Pi OS document
Ce qu'il faut noter est l'élément de sensor_mode = 7. Le maximum est de 90 ips pour la picamera, mais de 200 ips pour le document Pi OS. 200fps est
1For frame rates over 120fps, it is necessary to turn off automatic exposure and gain control using
-ex off
. Doing so should achieve the higher frame rates, but exposure time and gains will need to be set to fixed values supplied by the user.
Il est nécessaire de désactiver l'exposition automatique et le contrôle de gain comme écrit, mais il semble que 120 ips soit pris en charge même si ce n'est pas le cas.
Cependant, pour les documents picamera
The maximum framerate of the camera depends on several factors. With overclocking, 120fps has been achieved on a V2 module but 90fps is the maximum supported framerate.
Il dit que 120 ips peuvent être émis en raison de facteurs tels que l'overclocking, mais la fréquence d'images maximale prise en charge est de 90 ips.
Lorsque j'ai réellement essayé de régler sensor_mode = 7, Resolution = (320,240), framerate = 120 en utilisant picamera, j'ai pu confirmer que 120fps était sorti. À propos, même dans le même sensor_mode, la réduction de la résolution est plus rapide en raison du redimensionnement par GPU et de la réduction de la quantité de transfert.
HQ (IMX477)
Raspberry Pi OS document
Les données HQ ne sont pas dans la documentation picamera, vous devez donc vous référer à la documentation du système d'exploitation Raspberry Pi.
J'ai en fait pris une image fixe en changeant sensor_mode, Resolution et use_video_port. C'est un peu long, donc si vous voulez l'ignorer, cliquez sur [ici](# Flux vers l'acquisition d'image).
Le tableau de test suivant a été imprimé sur du papier A4 et utilisé pour la prise de vue. La couleur d'arrière-plan correspond à la plage de prise de vue de chaque sensor_mode illustré ci-dessus. De plus, l'illustration de Irasutoya est utilisée pour faciliter la compréhension du changement d'angle de vue.
Les images prises en appuyant sur sensor_mode, Resolution et use_video_port sont affichées ci-dessous. La résolution est la résolution qui apparaît dans la table sensor_mode. L'image publiée est une capture d'écran de la vignette.
La direction horizontale (→) est la différence entre sensor_mode (1 à 7), et la direction verticale (↓) est la présence ou l'absence de Resolution et use_video_port. Le nom de fichier affiché sous l'image est
{Resolution}_{use_video_port}_{sensor_mode}.jpg
Il est.
→ sensor_mode (1~7) ↓ Résolution, use_video_port (False, True alternative)
Cela ressemble à l'ensemble, et lorsque le sensor_mode est le même, presque la même plage est affichée. À partir de là, on peut voir qu'après la prise de vue avec l'angle de vue sensor_mode spécifié, il est rogné et redimensionné à la taille de la résolution.
Il n'y a pas de changement dans la différence de use_video_port. Si sensor_mode est spécifié, la valeur de use_video_port sera-t-elle ignorée? Concernant la différence de quantité de bruit due à la différence de use_video_port, je pense qu'elle ne peut pas être comparée car le réglage au moment de la prise de vue est approprié, mais le ressenti que j'ai vu était le même.
Si vous regardez la différence de sensor_mode, vous pouvez voir qu'il y a une différence dans la plage de prise de vue. Il s'agit de la différence d'angle d'image en fonction du sensor_mode. Vous trouverez ci-dessous l'image lorsque la résolution et le sensor_mode correspondent. Sur l'image, vous pouvez voir que la couleur d'arrière-plan de la carte de test correspond à la plage de prise de vue.
(1920,1080)_False_1.jpg (sensor_mode=1)
(3280, 2464)_False_2.jpg (sensor_mode=2)
(3280, 2464)_False_3.jpg (sensor_mode=3)
(1640, 1232)_False_4.jpg (sensor_mode=4)
(1640, 922)_False_5.jpg (sensor_mode=5)
(1280, 720)_False_6.jpg (sensor_mode=6)
(640, 480)_False_7.jpg (sensor_mode=7)
Ensuite, les résultats de la modification de Resolution et de sensor_mode sans spécifier sensor_mode sont affichés ci-dessous. Le nom du fichier est le même qu'avant
{Resolution}_{use_video_port}_{sensor_mode}.jpg
(Puisque sensor_mode n'est pas spécifié, il vaut 0). La direction horizontale (→) est la présence ou l'absence de use_video_port, et la direction verticale (↓) est la différence de résolution.
Lorsque use_video_port = False (colonne de gauche), l'image montre "l'illustration du livre AI", indiquant que toutes les images ont été prises dans la plage de prise de vue maximale.
Ensuite, si vous regardez quand use_video_port = True (colonne de droite), l'image est la même que celle de gauche sauf pour (1920,1080). Cependant, il est plus naturel de définir use_video_port = True sur sensor_mode, qui est le plus proche de Resolution (par exemple, (640, 480) rétrécit l'angle de vue).
Ce comportement est dû à la méthode de détermination du sensor_mode de picamera, et il semble que picamera dispose d'un mécanisme pour déterminer sensor_mode en tenant compte de la résolution et de la fréquence d'images. (Référence) https://picamera.readthedocs.io/en/release-1.13/fov.html#sensor-modes
Le résultat ci-dessus était le résultat de framerate = 30 (par défaut). Ensuite, je publierai le résultat avec une fréquence d'images = 60.
Comme vous pouvez le voir à partir du résultat de framerate = 60, la plage de prise de vue lorsque use_video_port = True a changé. Auparavant, seule la zone jaune était affichée (1920, 1080), mais maintenant elle est affichée jusqu'à la plage bleue. Cela signifie que sensor_mode = 1 n'est pas compatible avec 60fps, il a donc été changé en sensor_mode = 6.
Puisque les autres images sont également affichées dans la gamme bleue, on peut voir qu'elles ont été prises avec sensor_mode = 6. En outre, on peut voir que (640, 480) a sensor_mode = 7 en considération de la résolution.
Enfin, c'est le résultat du changement de Resolution et de sensor_mode sans spécifier use_video_port.
Lorsque framerate = 30
Lorsque framerate = 60
D'après le résultat, nous pouvons voir que c'est la même chose que la première vérification. Puisqu'il ne change pas même si le framerate est changé, il semble que la relation hiérarchique des paramètres soit sensor_mode> framerate.
En utilisant l'image de 1640x922, use_video_port = False, nous avons comparé sensor_mode = 4 (binning 2x2) et sensor_mode = 2 (résolution maximale redimensionnée sans binning). La gauche est sensor_mode = 4 et la droite est sensor_mode = 2. L'image publiée est une capture d'écran de deux images affichées côte à côte sur le logiciel de visualisation.
Gauche: sensor_mode = 4 (binning), Droite: sensor_mode = 2
Gauche: sensor_mode = 4 (binning), Droite: sensor_mode = 2
Je pense que la résolution avec binning est inférieure à celle sans binning. Probablement, la résolution est réduite car le traitement de la démosaïque est effectué après le binning. Si vous photographiez avec la priorité sur la résolution, il semble préférable de filmer à la résolution maximale sans binning, même si vous redimensionnez plus tard.
Bien que cela n'ait pas été vérifié cette fois, l'effet de réduction du bruit du binning peut apparaître lors de la prise de vue dans un environnement sombre. De plus, comme nous n'avons pas défini de paramètres liés à l'exposition et à la balance des blancs cette fois, il peut être préférable de ne pas comparer la sensation de bruit dans l'image ci-dessus.
Pour le moment, j'écrirai les paramètres que j'ai notés lors de la prise de ces deux images. La vitesse d'obturation est légèrement différente et la valeur de la balance des blancs est différente, mais je ne pense pas que cela affectera la comparaison de la résolution.
parameters | sensor_mode=4 images | sensor_mode=2 images |
---|---|---|
resolution | 1640x922 | 1640x922 |
exposure_speed | 25605 (us) | 25832 (us) |
sensor_mode | 4 | 2 |
analog_gain | 1 | 1 |
digital_gain | 1 | 1 |
framerate | 30 | 30 |
awb_gains | (Fraction(205, 128), Fraction(235, 128)) | (Fraction(205, 128), Fraction(471, 256)) |
À partir des résultats ci-dessus, le flux de traitement lié à la taille de l'image, qui est effectué de la prise de vue à l'obtention d'une image, est illustré sur la base de trois types d'exemples. (Le traitement indiqué dans cette section comprend mes attentes, l'exactitude ne peut donc pas être garantie.)
Table: table de correspondance sensor_mode du module v2 (pièce)
sensor_mode | Resolution | FoV | Binning |
---|---|---|---|
1 | 1920x1080 | Partial | None |
Le tableau ci-dessus fait partie du tableau du module v2 publié précédemment. sensor_mode = 1 est le mode de 1920x1080. Lors de la prise de vue, puisque FoV est partiel, elle sera prise en utilisant une partie du capteur (partie orange).
Après cela, il est rogné au format d'image de résolution spécifié (ici 3280x2464) (4: 3) et redimensionné.
Table: table de correspondance sensor_mode du module v2 (pièce)
sensor_mode | Resolution | FoV | Binning |
---|---|---|---|
2 | 3280x2464 | Full | None |
Il s'agit du même processus que lors de l'utilisation du port d'image fixe sans spécifier sensor_mode. Étant donné que la qualité d'image la plus élevée est utilisée dans le port d'image fixe, elle est lente car un tel traitement se produit même à 800x600.
Table: table de correspondance sensor_mode du module v2 (pièce)
sensor_mode | Resolution | FoV | Binning |
---|---|---|---|
7 | 640x480 | Partial | 2x2 |
Le binning des pixels est effectué à sensor_mode = 7. Par conséquent, la plage de 1280x960 du capteur est utilisée, et elle devient 640x480 par binning. Après cela, il sera redimensionné à la résolution spécifiée.
A resolution of 800x600 and a framerate of 60fps will select the 640x480 60fps mode, even though it requires upscaling because the algorithm considers the framerate to take precedence in this case.
Citation: https://picamera.readthedocs.io/en/release-1.13/fov.html#sensor-modes
Selon la documentation picamera, le redimensionnement ne diminue pas toujours en fonction de la fréquence d'images que vous définissez.
Lors de cette vérification, nous avons confirmé la survenue d'une mise à l'échelle due à la limitation de la fréquence d'images. Si vous souhaitez éviter la conversion ascendante et prendre des photos avec une qualité d'image élevée, vous devez définir sensor_mode manuellement.
Il s'agit du code source utilisé pour cette vérification. Je pense qu'il n'y a pas de problème car la différence de sensor_mode apparaît bien dans ce code. Pour être inquiet
Il existe un tel endroit, mais je ne l'ai pas confirmé. De plus, la mise en veille avant la prise de vue est de 1 seconde, mais lors de la prise de vue de quelque chose, il est préférable de prendre environ 2 secondes car l'exposition et la balance des blancs sont liées. Cette fois, la vérification de l'angle de vue est la principale, elle convient donc.
write_config ()
est une fonction qui écrit les paramètres de l'appareil photo (vitesse d'obturation, etc.). Il n'est pas directement lié à la vérification de sensor_mode.
import picamera
import numpy as np
import cv2
from PIL import Image
import io
import os, sys
import datetime
import time
def write_config(f, camera):
"""
Une fonction qui exporte tous les paramètres qui peuvent être exportés par la caméra
"""
f.writelines(f"timestamp*={camera.timestamp}\n")
f.writelines(f"revision={camera.revision}\n")
f.writelines(f"resolution={camera.resolution}\n")
f.writelines(f"-"*30)
f.writelines("\n")
shutter_speed = camera.shutter_speed
exposure_speed = camera.exposure_speed
if(shutter_speed!=0):
f.writelines("shutter_speed={0} (1/{1:.2f}s)\n".format(shutter_speed, 1/(shutter_speed/1000000)))
else:
f.writelines("shutter_speed={0}\n".format(shutter_speed))
f.writelines("exposure_speed*={0} (1/{1:.2f}s)\n".format(exposure_speed, 1/(exposure_speed/1000000)))
f.writelines(f"exposure_mode={camera.exposure_mode}\n")
f.writelines(f"exposure_compensation={camera.exposure_compensation}\n")
f.writelines(f"iso={camera.iso}\n")
f.writelines(f"sensor_mode={camera.sensor_mode}\n")
f.writelines(f"analog_gain*={camera.analog_gain}\n")
f.writelines(f"digital_gain*={camera.digital_gain}\n")
f.writelines(f"framerate={camera.framerate}\n")
f.writelines(f"framerate_delta={camera.framerate_delta}\n")
f.writelines(f"framerate_range={camera.framerate_range}\n")
f.writelines(f"meter_mode={camera.meter_mode}\n")
f.writelines(f"drc_strength={camera.drc_strength}\n")
f.writelines(f"raw_format={camera.raw_format}\n")
f.writelines("-"*30)
f.writelines("\n")
f.writelines(f"image_denoise={camera.image_denoise}\n")
f.writelines(f"video_denoise={camera.video_denoise}\n")
f.writelines(f"video_stabilization={camera.video_stabilization}\n")
f.writelines("-"*30)
f.writelines("\n")
f.writelines(f"awb_gains= {camera.awb_gains}\n")
f.writelines(f"awb_mode= {camera.awb_mode}\n")
f.writelines(f"brightness= {camera.brightness}\n")
f.writelines(f"saturation= {camera.saturation}\n")
f.writelines(f"contrast= {camera.contrast}\n")
f.writelines(f"sharpness= {camera.sharpness}\n")
f.writelines(f"flash_mode= {camera.flash_mode}\n")
f.writelines(f"rotation= {camera.rotation}\n")
f.writelines(f"hflip= {camera.hflip}\n")
f.writelines(f"vflip= {camera.vflip}\n")
f.writelines(f"zoom= {camera.zoom}\n")
f.writelines("-"*30)
f.writelines("\n")
f.writelines(f"color_effects={camera.color_effects}\n")
f.writelines(f"image_effect={camera.image_effect}\n")
f.writelines(f"image_effect_params={camera.image_effect_params}\n")
f.writelines(f"still_stats={camera.still_stats}\n")
# -----------Paramètre utilisé pour la vérification--------------
RESOLUTION_LIST = ((3280, 2464), # full sensor area #2, #3
(1640, 1232), # full sensor area(binned) #4
(1640, 922), # #5
(1280,720), # #6
(1920, 1080), # #1
(640, 480)) # #7
FRAMERATE = (30, 60)
USE_VIDEO_PORT = (True, False)
SENSOR_MODES = (1,2,3,4,5,6,7)
nowtime = datetime.datetime.now()
outputdir = nowtime.strftime("%Y%m%d-%H%M%S")
os.mkdir(outputdir)
TEST1 = True
TEST2 = True
TEST3 = True
# -----------------------------------------------------
"""
test1
Resolution, use_video_port, sensor_Testez pour atteindre toutes les combinaisons de modes
"""
if(TEST1):
foldername = os.path.join(outputdir, "test1")
os.mkdir(foldername)
for resolution in RESOLUTION_LIST:
for use_vp in USE_VIDEO_PORT:
for sensor_mode in SENSOR_MODES:
with picamera.PiCamera() as camera:
camera.resolution = resolution
camera.sensor_mode = sensor_mode
camera.start_preview()
time.sleep(1)
stream = io.BytesIO()
camera.capture(stream, format="jpeg", use_video_port=use_vp, quality=95)
camera.stop_preview()
stream.seek(0)
img = Image.open(stream)
img = np.array(img, dtype=np.uint8)
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
filename = "{0}_{1}_{2}.jpg ".format(str(resolution), str(use_vp), str(sensor_mode))
cv2.imwrite(os.path.join(foldername, filename), img)
#cv2.imshow("capture", img)
print(filename)
print(img.shape)
print("")
with open(os.path.join(foldername, filename[:-4]+".txt"), "w") as f:
write_config(f, camera)
"""
test2
sensor_Test lorsque le mode n'est pas spécifié
"""
if(TEST2):
for framerate in FRAMERATE:
foldername = os.path.join(outputdir, "test2_{0}fps".format(framerate))
os.mkdir(foldername)
for resolution in RESOLUTION_LIST:
for use_vp in USE_VIDEO_PORT:
with picamera.PiCamera() as camera:
camera.resolution = resolution
camera.framerate = framerate
# camera.sensor_mode = sensor_mode # sensor_Ne spécifiez pas le mode
camera.start_preview()
time.sleep(1)
stream = io.BytesIO()
camera.capture(stream, format="jpeg", use_video_port=use_vp, quality=95)
camera.stop_preview()
stream.seek(0)
img = Image.open(stream)
img = np.array(img, dtype=np.uint8)
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
filename = "{0}_{1}_{2}.jpg ".format(str(resolution), str(use_vp), str(camera.sensor_mode))
cv2.imwrite(os.path.join(foldername, filename), img)
#cv2.imshow("capture", img)
print(filename)
print(img.shape)
print("")
with open(os.path.join(foldername, filename[:-4]+".txt"), "w") as f:
write_config(f, camera)
"""
test3
use_video_Test lorsque le port n'est pas spécifié
"""
if(TEST3):
for framerate in FRAMERATE:
foldername = os.path.join(outputdir, "test3_{0}fps".format(framerate))
os.mkdir(foldername)
for resolution in RESOLUTION_LIST:
for sensor_mode in SENSOR_MODES:
with picamera.PiCamera() as camera:
camera.resolution = resolution
camera.sensor_mode = sensor_mode
camera.framerate = framerate
camera.start_preview()
time.sleep(1)
stream = io.BytesIO()
camera.capture(stream, format="jpeg", quality=95) # use_video_Ne spécifiez pas le port
camera.stop_preview()
stream.seek(0)
img = Image.open(stream)
img = np.array(img, dtype=np.uint8)
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
filename = "{0}_{1}_{2}.jpg ".format(str(resolution), "None", str(sensor_mode))
cv2.imwrite(os.path.join(foldername, filename), img)
#cv2.imshow("capture", img)
print(filename)
print(img.shape)
print("")
with open(os.path.join(foldername, filename[:-4]+".txt"), "w") as f:
write_config(f, camera)
Il est possible de filmer sans être conscient de sensor_mode, mais j'ai trouvé que je devais prendre en compte le type de performances (haute qualité d'image, angle de vue, vitesse) dont j'ai besoin. Personnellement, j'ai été surpris que la diminution de la résolution due au binning des pixels soit supérieure à ce à quoi je m'attendais.
La majeure partie de cet article est tirée de la documentation picamera. Le document picamera décrit non seulement comment utiliser la bibliothèque, mais également le mécanisme du module de caméra et le déroulement de la prise de vue, et il est très utile, nous vous recommandons donc de le lire.
https://picamera.readthedocs.io/en/release-1.13/index.html (document picaemra) https://www.raspberrypi.org/documentation/raspbian/applications/camera.md (Documentation pour l'application caméra Raspberry Pi)
Recommended Posts