Michael
Michael

Reputation: 29

Video Output Turns Blue

So what im trying to do is show the original frame ( video feed from cam ) and show that video with bounding box with hardcoded cordinate, but what happen was the feed that i got is a bit blue and weird looking but inside the bounding box is fine as it should be. Also i tried another script just to see if my camera is broken but no it shows up just fine. Thank you for your help.

import cv2
import numpy as np
import tkinter as tk
from PIL import ImageTk,Image

def keluar():
    app.destroy()
    cv2.destroyAllWindows()
    vid.release()
    print ("quiting...")

def stream1():
    global num_frames
    _, frame = vid.read()
    clone = frame.copy()
    frame = cv2.flip(frame,1)
    clone = frame.copy()
    (height, width) = frame.shape[:2]
    frame1 = frame[top:bottom, right:left]
    frame2 = cv2.cvtColor(frame1,cv2.COLOR_BGR2HSV)
    frame3 = cv2.inRange(frame2,lower,upper)
    frame4 = cv2.GaussianBlur(frame3,(5,5),0)

    if num_frames < 30:
        run_avg(frame4, aWeight)
    else:
        hand = segment(frame4)

        if hand is not None:
            (thd, segmented) = hand
            cv2.drawContours(clone, [segmented + (right, top)], -1, (0, 0, 255))
            cv2.imshow("Thesholded", thd)
        cv2.rectangle(clone, (left, top), (right, bottom), (0,255,0), 2)
        num_frames += 1

    #Show video
    img1 = Image.fromarray(clone)
    imgtk1 = ImageTk.PhotoImage(image=img1)
    lframe.imgtk = imgtk1
    lframe.configure(image=imgtk1)
    lframe.after(1,stream1)

def run_avg(image, aWeight):
    global bg
    if bg is None:
        bg = image.copy().astype("float")
        return
    cv2.accumulateWeighted(image, bg, aWeight)

def segment(image, threshold=25):
    global bg
    diff = cv2.absdiff(bg.astype("uint8"), image)
    thd = cv2.threshold(diff, threshold, 255, cv2.THRESH_BINARY)[1]
    (_, cnts, _) = cv2.findContours(thd.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    if len(cnts) == 0:
        return
    else:
        segmented = max(cnts, key=cv2.contourArea)
        return (thd, segmented)


aWeight = 0
num_frames = 0
top, right, bottom, left = 10, 350, 225, 590
bg = None
vid = cv2.VideoCapture(0)
app = tk.Tk()
kotak = tk.Frame(app,bg="white")
kotak.grid()
lframe = tk.Label(kotak)
lframe.grid(column=0,row=0)
lframe2 = tk.Label(kotak,text="Output",font=("arial",20))
lframe2.grid(column=2,row=0,rowspan=2,padx=20,pady=20)
bstart = tk.Button(kotak,text="Start")
bstart.grid(column=0,row=1,columnspan=2,ipadx=100,ipady=50,padx=20,pady=20)
bexit = tk.Button(kotak,text="Exit",command=keluar)
bexit.grid(column=1,row=1,columnspan=2,ipadx=50,ipady=30,padx=20,pady=20)
kernel = np.ones((5,5),np.uint8)
lower = np.array([0, 58, 50])
upper = np.array([30, 255, 255])

#==========================================
stream1()
app.mainloop()

Upvotes: 0

Views: 327

Answers (1)

furas
furas

Reputation: 142909

cv2 gives frame always in BGR which is blue if you don't convert it to RGB.

Only cv2.imshow() shows BGR correctly without converting.

To display correctly in other tool you have to use

frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

Upvotes: 2

Related Questions