# Issue with Camera appearing blue

**URL:** https://forum.opencv.org/t/issue-with-camera-appearing-blue/15466
**Category:** Python
**Tags:** raspberrypi, imgproc
**Created:** [November 10, 2023, 5:16am UTC](https://forum.opencv.org/t/issue-with-camera-appearing-blue/15466 "2023-11-10T05:16:25Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![FordMontana](https://avatars.discourse-cdn.com/v4/letter/f/f08c70/32.png) [@FordMontana](https://forum.opencv.org/u/FordMontana)
#### Post date: [November 10, 2023, 5:16am UTC](https://forum.opencv.org/t/issue-with-camera-appearing-blue/15466/1 "2023-11-10T05:16:25Z")

</div>

The feed of my picamera2 is a bluish-greenish hue to it.  
[Blue-ish Image](https://imgur.com/a/jeE99pu)  
As seen here the jacket appears blue, but the jacket is actually a burgundy color as seen below.  
[Normal Image](https://imgur.com/a/bsA40Zq)

I thought it was this line in my code that was giving me issue.

```auto
 frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

```

However when I attempted to change it with lines like

```auto
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV))

```

There was no difference to the image.

But when I attempt …

```auto
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_GRAY2RGB

```

I would get the error…

```auto
FordMontana@raspberrypi:~/tflite1 $ python webcam.py --modeldir=custom_model_lite
INFO: Created TensorFlow Lite XNNPACK delegate for CPU.
[1:20:30.191125045] [63006] INFO Camera camera_manager.cpp:297 libcamera v0.0.5+83-bde9b04f
[1:20:30.221183718] [63010] WARN RPI vc4.cpp:383 Mismatch between Unicam and CamHelper for embedded data usage!
[1:20:30.222036114] [63010] INFO RPI vc4.cpp:437 Registered camera /base/soc/i2c0mux/i2c@1/imx219@10 to Unicam device /dev/media2 and ISP device /dev/media1
[1:20:30.222117798] [63010] INFO RPI pipeline_base.cpp:1101 Using configuration file '/usr/share/libcamera/pipeline/rpi/vc4/rpi_apps.yaml'
[1:20:30.228234194] [63006] INFO Camera camera.cpp:1033 configuring streams: (0) 1280x720-XBGR8888 (1) 1920x1080-SBGGR10_CSI2P
[1:20:30.228814816] [63010] INFO RPI vc4.cpp:565 Sensor: /base/soc/i2c0mux/i2c@1/imx219@10 - Selected sensor format: 1920x1080-SBGGR10_1X10 - Selected unicam format: 1920x1080-pBAA
Traceback (most recent call last):
  File "/home/FordMontana/tflite1/webcam.py", line 164, in <module>
    frame_rgb = cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR)
cv2.error: OpenCV(4.5.1) ../modules/imgproc/src/color.simd_helpers.hpp:92: error: (-2:Unspecified error) in function 'cv::impl::{anonymous}::CvtHelper<VScn, VDcn, VDepth, sizePolicy>::CvtHelper(cv::InputArray, cv::OutputArray, int) [with VScn = cv::impl::{anonymous}::Set<1>; VDcn = cv::impl::{anonymous}::Set<3, 4>; VDepth = cv::impl::{anonymous}::Set<0, 2, 5>; cv::impl::{anonymous}::SizePolicy sizePolicy = cv::impl::<unnamed>::NONE; cv::InputArray = const cv::_InputArray&; cv::OutputArray = const cv::_OutputArray&]'
> Invalid number of channels in input image:
> 'VScn::contains(scn)'
> where
> 'scn' is 4

```

Also you can see that the format is 1920x1080, no matter what i put as my resolution it was always formatted this way.

My code is below.

```auto
import os
import argparse
import cv2
import numpy as np
import sys
import time
from threading import Thread
import importlib.util

from picamera2 import Picamera2, Preview

# Define VideoStream class to handle streaming of video from Picamera2 in separate processing thread
class VideoStream:
    """Camera object that controls video streaming from the Picamera2"""
    def __init__ (self, resolution=(20,10), framerate=30):
# Define and parse input arguments
parser = argparse.ArgumentParser()
parser.add_argument('--modeldir', help='Folder the .tflite file is located in',
                    required=True)
parser.add_argument('--graph', help='Name of the .tflite file, if different than detect.tflite',
                    default='detect.tflite')
parser.add_argument('--labels', help='Name of the labelmap file, if different than labelmap.txt',
                    default='labelmap.txt')
parser.add_argument('--threshold', help='Minimum confidence threshold for displaying detected objects',
                    default=0.5)
parser.add_argument('--resolution', help='Desired webcam resolution in WxH. If the webcam does not support the resolution entered, errors may occur.',
                    default='1280x720')
parser.add_argument('--edgetpu', help='Use Coral Edge TPU Accelerator to speed up detection',
                    action='store_true')

args = parser.parse_args()

MODEL_NAME = args.modeldir
GRAPH_NAME = args.graph
LABELMAP_NAME = args.labels
min_conf_threshold = float(args.threshold)
resW, resH = args.resolution.split('x')
imW, imH = int(resW), int(resH)
use_TPU = args.edgetpu

# Import TensorFlow libraries
# If tflite_runtime is installed, import interpreter from tflite_runtime, else import from regular tensorflow
# If using Coral Edge TPU, import the load_delegate library
pkg = importlib.util.find_spec('tflite_runtime')
if pkg:
    from tflite_runtime.interpreter import Interpreter
    if use_TPU:
        from tflite_runtime.interpreter import load_delegate
else:
    from tensorflow.lite.python.interpreter import Interpreter
    if use_TPU:
        from tensorflow.lite.python.interpreter import load_delegate

# If using Edge TPU, assign filename for Edge TPU model
if use_TPU:
    # If user has specified the name of the .tflite file, use that name, otherwise use default 'edgetpu.tflite'
    if (GRAPH_NAME == 'detect.tflite'):
        GRAPH_NAME = 'edgetpu.tflite'      

# Get path to current working directory
CWD_PATH = os.getcwd()

# Path to .tflite file, which contains the model that is used for object detection
PATH_TO_CKPT = os.path.join(CWD_PATH,MODEL_NAME,GRAPH_NAME)

# Path to label map file
PATH_TO_LABELS = os.path.join(CWD_PATH,MODEL_NAME,LABELMAP_NAME)

# Load the label map
with open(PATH_TO_LABELS, 'r') as f:
    labels = [line.strip() for line in f.readlines()]

# Have to do a weird fix for label map if using the COCO "starter model" from
# https://www.tensorflow.org/lite/models/object_detection/overview
# First label is '???', which has to be removed.
if labels[0] == '???':
    del(labels[0])

# Load the Tensorflow Lite model.
# If using Edge TPU, use special load_delegate argument
if use_TPU:
    interpreter = Interpreter(model_path=PATH_TO_CKPT,
                              experimental_delegates=[load_delegate('libedgetpu.so.1.0')])
    print(PATH_TO_CKPT)
else:
    interpreter = Interpreter(model_path=PATH_TO_CKPT)

interpreter.allocate_tensors()

# Get model details
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
height = input_details[0]['shape'][1]
width = input_details[0]['shape'][2]

floating_model = (input_details[0]['dtype'] == np.float32)

input_mean = 127.5
input_std = 127.5

# Check output layer name to determine if this model was created with TF2 or TF1,
# because outputs are ordered differently for TF2 and TF1 models
outname = output_details[0]['name']

if ('StatefulPartitionedCall' in outname): # This is a TF2 model
    boxes_idx, classes_idx, scores_idx = 1, 3, 0
else: # This is a TF1 model
    boxes_idx, classes_idx, scores_idx = 0, 1, 2

# Initialize frame rate calculation
frame_rate_calc = 1
freq = cv2.getTickFrequency()

# Initialize video stream
videostream = VideoStream(resolution=(imW,imH),framerate=30).start()
time.sleep(1)

#for frame1 in camera.capture_continuous(rawCapture, format="bgr",use_video_port=True):
while True:

    # Start timer (for calculating frame rate)
    t1 = cv2.getTickCount()

    # Grab frame from video stream
    frame1 = videostream.read()

    # Acquire frame and resize to expected shape [1xHxWx3]
    frame = frame1.copy()
    frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    frame_resized = cv2.resize(frame_rgb, (width, height))
    input_data = np.expand_dims(frame_resized, axis=0)

    # Normalize pixel values if using a floating model (i.e. if model is non-quantized)
    if floating_model:
        input_data = (np.float32(input_data) - input_mean) / input_std

    # Perform the actual detection by running the model with the image as input
    interpreter.set_tensor(input_details[0]['index'],input_data)
    interpreter.invoke()

    # Retrieve detection results
    boxes = interpreter.get_tensor(output_details[boxes_idx]['index'])[0] # Bounding box coordinates of detected objects
    classes = interpreter.get_tensor(output_details[classes_idx]['index'])[0] # Class index of detected objects
    scores = interpreter.get_tensor(output_details[scores_idx]['index'])[0] # Confidence of detected objects

    # Loop over all detections and draw detection box if confidence is above minimum threshold
    for i in range(len(scores)):
        if ((scores[i] > min_conf_threshold) and (scores[i] <= 1.0)):

            # Get bounding box coordinates and draw box
            # Interpreter can return coordinates that are outside of image dimensions, need to force them to be within image using max() and min()
            ymin = int(max(1,(boxes[i][0] * imH)))
            xmin = int(max(1,(boxes[i][1] * imW)))
            ymax = int(min(imH,(boxes[i][2] * imH)))
            xmax = int(min(imW,(boxes[i][3] * imW)))
           
            cv2.rectangle(frame, (xmin,ymin), (xmax,ymax), (10, 255, 0), 2)

            # Draw label
            object_name = labels[int(classes[i])] # Look up object name from "labels" array using class index
            label = '%s: %d%%' % (object_name, int(scores[i]*100)) # Example: 'person: 72%'
            labelSize, baseLine = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.7, 2) # Get font size
            label_ymin = max(ymin, labelSize[1] + 10) # Make sure not to draw label too close to top of window
            cv2.rectangle(frame, (xmin, label_ymin-labelSize[1]-10), (xmin+labelSize[0], label_ymin+baseLine-10), (255, 255, 255), cv2.FILLED) # Draw white box to put label text in
            cv2.putText(frame, label, (xmin, label_ymin-7), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 0), 2) # Draw label text

    # Draw framerate in corner of frame
    cv2.putText(frame,'FPS: {0:.2f}'.format(frame_rate_calc),(30,50),cv2.FONT_HERSHEY_SIMPLEX,1,(255,255,0),2,cv2.LINE_AA)

    # All the results have been drawn on the frame, so it's time to display it.
    cv2.imshow('Object detector', frame)

    # Calculate framerate
    t2 = cv2.getTickCount()
    time1 = (t2-t1)/freq
    frame_rate_calc= 1/time1

    # Press 'q' to quit
    if cv2.waitKey(1) == ord('q'):
        break

# Clean up
cv2.destroyAllWindows()
videostream.stop()

```

Help would be greatly appreciated. Thank you.

---

<div class="post-metadata">

### Author: ![matti.vuori](https://avatars.discourse-cdn.com/v4/letter/m/e79b87/32.png) [@matti.vuori](https://forum.opencv.org/u/matti.vuori)
#### Post date: [November 10, 2023, 5:35am UTC](https://forum.opencv.org/t/issue-with-camera-appearing-blue/15466/2 "2023-11-10T05:35:54Z")

</div>

Instead of having that line, or replacing with something else, why don’t you just leave it out…

---

<div class="post-metadata">

### Author: ![FordMontana](https://avatars.discourse-cdn.com/v4/letter/f/f08c70/32.png) [@FordMontana](https://forum.opencv.org/u/FordMontana)
#### Post date: [November 10, 2023, 12:40pm UTC](https://forum.opencv.org/t/issue-with-camera-appearing-blue/15466/3 "2023-11-10T12:40:24Z")

</div>

I forgot to mention that I also attempted to do that, however I get the error that dimensions don’t work out when done this way.

```auto
/imx219@10 - Selected sensor format: 1920x1080-SBGGR10_1X10 - Selected unicam format: 1920x1080-pBAA
Traceback (most recent call last):
  File "/home/FordMontana/tflite1/webcam.py", line 173, in <module>
    interpreter.set_tensor(input_details[0]['index'],input_data)
  File "/home/FordMontana/.local/lib/python3.9/site-packages/tflite_runtime/interpreter.py", line 720, in set_tensor
    self._interpreter.SetTensor(tensor_index, value)
ValueError: Cannot set tensor: Dimension mismatch. Got 4 but expected 3 for dimension 3 of input 0.

```

Perhaps I am not removing it properly, but the way I went about it is shown below.

```auto
   # Acquire frame and resize to expected shape [1xHxWx3]
    frame = frame1.copy()
    #frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    frame_resized = cv2.resize(frame, (width, height))
    input_data = np.expand_dims(frame_resized, axis=0)

    # Normalize pixel values if using a floating model (i.e. if model is non-quantized)
    if floating_model:
        input_data = (np.float32(input_data) - input_mean) / input_std

    # Perform the actual detection by running the model with the image as input
    interpreter.set_tensor(input_details[0]['index'],input_data)
    interpreter.invoke()

```
