Color thresholding on an opencv video

≯℡__Kan透↙ 提交于 2019-12-22 17:49:48

问题


I am thresholding for a color range in an opencv video. The goal is to seperate the B-mode (black and white, information on location but not velocity) from color-flow doppler mode (velocity infomation) in medical ultrasound videos for an academic project. I have tried to threshold based on an HSV hue range that I have rebuilt from the color scale delivered by the ultrasound machine (light blue [opencv hue 90] to yellow [opencv hue 35]). Unfortunately, the results are not good. Have I made a mistake in the thresholding? Or would there be a another way to achieve the desired results? Below is my code and a frame example of my results.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

##IMPORTS
import cv2.cv as cv
import numpy as np

##VARIABLES
#colors
doppler_hues=np.concatenate([np.arange(90,181),np.arange(0,36)])

##MAIN
#start video stream analysis
frames = raw_input('Please enter video file:')
if not frames:
   print "This program requires a file as input!"
   sys.exit(1)


# first, create the necessary windows
cv.NamedWindow ('image', cv.CV_WINDOW_AUTOSIZE)
cv.NamedWindow ('original', cv.CV_WINDOW_AUTOSIZE)

#File capture
vidFile = cv.CaptureFromFile(frames)
nFrames = int(  cv.GetCaptureProperty( vidFile, cv.CV_CAP_PROP_FRAME_COUNT ) )
fps = cv.GetCaptureProperty( vidFile, cv.CV_CAP_PROP_FPS )
waitPerFrameInMillisec = int( 1/fps * 1000/1 )


for f in xrange( nFrames ):
   #frame capture
   frame = cv.QueryFrame( vidFile )

   # create the images we need
   original = cv.CreateImage (cv.GetSize (frame), 8, 3)
   cv.Copy(frame,original)
   image = cv.CreateImage (cv.GetSize (frame), 8, 3)
   cv.CvtColor(frame, image, cv.CV_BGR2HSV)
   image2 = cv.CreateImage (cv.GetSize (frame), 8, 3)

   if not frame:
      break

   #Replace pixel colors
   image=np.asarray(image[:,:])
   hue=np.resize(image,(480,640,1))
   hue[np.where((np.not_equal(hue,doppler_hues)).all(axis=2))]=[0]
   hue2=np.resize(hue,(480,640,3))
   image[np.where((hue2==[0,0,0]).all(axis=2))]=[0,0,0]

   image=cv.fromarray(image[:,:])
   cv.CvtColor(image, image2, cv.CV_HSV2BGR)

   #show the image
   cv.ShowImage("image", image2)
   cv.ShowImage("original", original)

   #quit command ESC
   if cv.WaitKey(waitPerFrameInMillisec)==27:
      break
   else:
      cv.WaitKey(waitPerFrameInMillisec) % 0x100

cv.DestroyAllWindows()

回答1:


Thresholding based on only the Hue component is somehow useless.
As you can see below, for a speceific Hue, the range of possible colors also includes gray colors.

Also, seeing the H,S,V channels, I can say that H channel alone can't help you. You should also use the Saturation channel:


(Hue Channel)

Though, you can see the Saturation channel can help you find the colorful areas easier:

Filtering Saturation<180 colors, would give you this:

Now you have the colorful areas. if that sidebar, is always in the picture you process, you can just filter the Value<150 in the Value channel to filter them out too:

And BTW, using cv2, your code becomes much more readable and easier to maintain:

import cv2

img = cv2.imread('image.png')
image_thr = img.copy()

imh = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
image_thr[(imh[...,1]<180) | (imh[...,2]<150)]=0

cv2.imshow('filtered',image_thr)


来源:https://stackoverflow.com/questions/16882928/color-thresholding-on-an-opencv-video

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!