pageauc / pi-timolo

Raspberry PI-TIMOLO ( PI-TImelapse, MOtion, LOwLight ) uses RPI picamera and OpenCV for Remote Headless Security Monitoring using Motion Tracking, Rclone Auto Sync files with remote storage services. Auto Twilight Transitions and Low Light Camera Settings. Panoramic images using PanTiltHat and More. This project is featured on GitHub Awesome software.
MIT License
548 stars 101 forks source link

Raspi IRcamera how to auto-change exposure time when light changes #124

Open AguedaDLV opened 2 years ago

AguedaDLV commented 2 years ago

Hi!, I am a beginner in python and raspberry I am using the four cameras adaptor from Arducam on my Raspberry for a project where I change the light intensity several times throughout the day. I am using crontab -e to run the program during all day, the cameras used to adjust their exposure time automatically but now they stopped doing it, and they do it only when I run the program manually, so now the pictures are very dark if I change from a high light to a low light and very bright if I change from a low light to a hight light. Does someone have a solution for this issue?

This is the code:

import RPi.GPIO as gp
import os
import cv2 as cv
import numpy as np
import time
import logging

class MultiAdapter:

    logging.basicConfig(filename='/home/pi/Desktop/agueda_imgs/example.log', level=logging.DEBUG)

    camera = cv.VideoCapture(0)
    camNum = 4
    adapter_info = {   "A":{   "i2c_cmd":"i2cset -y 1 0x70 0x00 0x04",
                                "gpio_sta":[0,0,1],
                        },
                    "B":{
                            "i2c_cmd":"i2cset -y 1 0x70 0x00 0x05",
                            "gpio_sta":[1,0,1],
                        },
                    "C":{
                            "i2c_cmd":"i2cset -y 1 0x70 0x00 0x06",
                            "gpio_sta":[0,1,0],
                        },
                    "D":{
                            "i2c_cmd":"i2cset -y 1 0x70 0x00 0x07",
                            "gpio_sta":[1,1,0],
                        },
                 }

    width = 240
    height = 320

    def release_all(self):
        for i in range(self.camNum):
           self.choose_channel(chr(65+i))
           self.camera.release()

    def __init__(self):
       #gp.setwarnings(False)
       gp.setmode(gp.BOARD)
       gp.setup(7, gp.OUT)
       gp.setup(11,gp.OUT)
       gp.setup(12,gp.OUT)

    def choose_channel(self,index):
        channel_info = self.adapter_info.get(index)
        if channel_info == None:
            print("Can't get this info")
        os.system(channel_info["i2c_cmd"]) # i2c write
        gpio_sta = channel_info["gpio_sta"] # gpio write
        gp.output(7, gpio_sta[0])
        gp.output(11, gpio_sta[1])
        gp.output(12, gpio_sta[2])

    def init(self,width,height):
        for i in range(self.camNum):
           self.height = height
           self.width = width
           self.choose_channel(chr(65+i))
           self.camera.set(3, self.width)
           self.camera.set(4, self.height)
           ret, frame = self.camera.read()
           if ret == True:
               print("camera %s init OK" %(chr(65+i)))
               pname = "image_"+ chr(65+i)+".jpg"
               cv.imwrite(pname,frame)

    def preview(self):
        font                   = cv.FONT_HERSHEY_PLAIN
        fontScale              = 1
        fontColor              = (255,255,255)
        lineType               = 1
        factor  = 20
        black = np.zeros(((self.height+factor)*2, self.width*2, 3), dtype= np.uint8)
        i = 0
        while True:
            self.choose_channel(chr(65+i))
            ret, frame = self.camera.read()
            ret, frame = self.camera.read()
            ret, frame = self.camera.read()
            print(ret)
            frame.dtype=np.uint8
            if i == 0:
                black[factor:factor+self.height, 0:self.width, :] = frame
                bottomLeftCornerOfText = (factor,factor)
                index = chr(65+i)
            elif i == 1:
                black[factor:factor+self.height, self.width:self.width*2,:] = frame
                bottomLeftCornerOfText = (factor+self.width, factor)
                index = chr(65+i)
            elif i == 2:
                black[factor*2+self.height:factor*2+self.height*2, 0:self.width,:] = frame
                bottomLeftCornerOfText = (factor, factor*2+self.height)
                index = chr(65+i)
            elif i == 3:
                black[factor*2+self.height:factor*2+self.height*2, self.width:self.width*2,:] = frame
                bottomLeftCornerOfText = (factor+self.width, factor*2+self.height)
                index = chr(65+i)
            i = i+1
            if i==self.camNum:
                i = 0
            cv.putText(black,'CAM '+index, bottomLeftCornerOfText, font, fontScale,fontColor,lineType)
            cv.imshow("Arducam Multi Camera Demo",black)
            if cv.waitKey(1) & 0xFF == ord('q'):
                del frame
                self.camera.release()
                cv.destroyAllWindows()
                break

    def save_imgs(self, parent_path, f_name, width,height):
        # Check if the folder exists
        # Create empty folders if not
        for i in range(self.camNum):
            directory_name = chr(65+i)
            path = os.path.join(parent_path, directory_name)

            if not os.path.isdir(path):
                os.makedirs(path)
                print("created folder " + chr(65+i))
            else:
                print("folder exists - " + chr(65+i))
        # logging data
        cnt = 0
        # Take imgs    
        for i in range(self.camNum):
            try:
                self.height = height
                self.width = width
                self.choose_channel(chr(65+i))
                time.sleep(0.5)
                self.camera.set(3, self.width)
                self.camera.set(4, self.height)
                ret, frame = self.camera.read()
                if ret == True:
                    directory_name = chr(65+i)
                    path = os.path.join(parent_path, directory_name)

                    pname = path + "//" + f_name +".jpg"
                    cv.imwrite(pname,frame)
                    print(f"camera {chr(65+i)} OK")
                    my_logging((f_name, directory_name, "worked"))
                    time.sleep(0.5)
                    cnt += 1
                else:
                    print(f"failed {chr(65+i)}")
                    my_logging((f_name, directory_name, "failed"))       
            except:
                logging.info(30*'-')
                logging.exception('')
                my_logging(f"{cnt} of 4 worked at {f_name}, temp was {check_temp()} deg.\n")

    for i in range(self.camNum):
        self.choose_channel(chr(65+i))
        self.camera.release()
        def check_temp():
        result = 0.0

    # The first line in this file holds the CPU temperature as an integer times 1000.
    # Read the first line and remove the newline character at the end of the string.
    if os.path.isfile('/sys/class/thermal/thermal_zone0/temp'):
        with open('/sys/class/thermal/thermal_zone0/temp') as f:
            line = f.readline().strip()
            # Test if the string is an integer as expected.
            if line.isdigit():
            # Convert the string with the CPU temperature to a float in degrees Celsius.
                result = float(line) / 1000
                return int(result)

    def my_logging(data):
        with open("/home/pi/Desktop/agueda_imgs/log_file.txt", "a") as logger:
            if len(data)>5:
                logger.write(data)
                logger.write(32*"-"+"\n")
           else:
                line = str(data) + "\n"
            logger.write(line)
pageauc commented 2 years ago

Class code you posted was not formatted properly in your github posting. Tried to fix but not sure it is correct indentation. You should post an attachment or repost to github with insert code block markup.

I do not have a four cameras adaptor from Arducam so cannot test the code. The code you posted is a class library. How are you executing the code and what version of python.