Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 创建轨迹栏以滚动大图像和上下边界(Pyhton/OpenCV)_Python_Opencv_Trackbar - Fatal编程技术网

Python 创建轨迹栏以滚动大图像和上下边界(Pyhton/OpenCV)

Python 创建轨迹栏以滚动大图像和上下边界(Pyhton/OpenCV),python,opencv,trackbar,Python,Opencv,Trackbar,我试图在OpenCv python创建的窗口中创建滚动条。具体来说,我想将答案(1)中的HSV滚动条形码与答案(2)中的放大缩小滚动条形码合并。两者都是分开工作的,但我想在同一个窗口中使用它们 代码(1)( 代码(2) #-*-编码:utf-8-*- 进口cv2 将numpy作为np导入 类PanZoomWindow(对象): “”“控制OpenCV窗口。注册鼠标侦听器以便: 1.右上/右下拖动可放大/缩小 2.右键单击重新居中 3.轨迹栏可垂直和水平滚动 如果指定不同的窗口名称,可以一次打开多

我试图在OpenCv python创建的窗口中创建滚动条。具体来说,我想将答案(1)中的HSV滚动条形码与答案(2)中的放大缩小滚动条形码合并。两者都是分开工作的,但我想在同一个窗口中使用它们

代码(1)(

代码(2)

#-*-编码:utf-8-*-
进口cv2
将numpy作为np导入
类PanZoomWindow(对象):
“”“控制OpenCV窗口。注册鼠标侦听器以便:
1.右上/右下拖动可放大/缩小
2.右键单击重新居中
3.轨迹栏可垂直和水平滚动
如果指定不同的窗口名称,可以一次打开多个窗口。
您可以传入一个onLeftClickFunction,当用户左键单击时,这个
将调用onLeftClickFunction(y,x),y,x在原始图像坐标中。”“”
def u uu init_uuuuu(self、img、windowName='PanZoomWindow',onLeftClickFunction=None):
self.WINDOW\u NAME=windowName
self.H\u轨迹栏\u名称='x'
self.V\u轨迹栏\u名称='y'
self.img=img
self.onLeftClickFunction=onLeftClickFunction
self.TRACKBAR_TICKS=1000
self.panAndZoomState=panAndZoomState(img.shape,self)
self.lButtonDownLoc=无
self.mbuttonownloc=无
self.rButtonDownLoc=无
cv2.namedWindow(self.WINDOW\u NAME,cv2.WINDOW\u NORMAL)
self.redrawImage()
cv2.setMouseCallback(self.WINDOW\u NAME,self.onMouse)
cv2.createTrackbar(self.H\u TRACKBAR\u NAME、self.WINDOW\u NAME、0、self.TRACKBAR\u TICKS、self.onHTrackbarMove)
cv2.createTrackbar(self.V\u TRACKBAR\u NAME、self.WINDOW\u NAME、0、self.TRACKBAR\u TICKS、self.onVTrackbarMove)
定义鼠标(自身、事件、x、y、_ignore1、_ignore2):
“”“响应窗口中的鼠标事件。
x和y是当前显示图像中的像素坐标。
如果用户已放大,则显示的图像是一个子区域,因此您需要
添加self.panAndZoomState.ul以获取完整图像中的坐标。”“”
如果event==cv2.event\u MOUSEMOVE:
返回
elif event==cv2.event\u RBUTTONDOWN:
#记录用户开始右拖动的位置
self.mbuttonownloc=np.array([y,x])
elif event==cv2.event\RBUTTONUP和self.MBUTDOWNLOC不是无:
#用户刚刚完成正确的拖动
dy=y-自.mButtonDownLoc[0]
pixelsPerDoubling=0.2*self.panAndZoomState.shape[0]#lower=zoom more
变化因子=(1.0+绝对值(dy)/像素倍增)
变更系数=最小值(最大值(1.0,变更系数),5.0)
如果变化系数<1.05:
dy=0#这是一次点击,不是画图。所以不要缩放,只需重新居中即可。
如果dy>0:#向下移动,则缩小。
zoomInFactor=1.0/changeFactor
其他:
zoomInFactor=changeFactor
#打印(“缩放因子:%s”%zoomFactor)
self.panAndZoomState.zoom(self.mButtonDownLoc[0],self.mButtonDownLoc[1],zoomInFactor)
elif event==cv2.event\u LBUTTONDOWN:
#用户按下了左键。
coordsInDisplayedImage=np.array([y,x])
如果np.any(CoordsInDisplayeImage<0)或np.any(CoordsInDisplayeImage>self.panAndZoomState.shape[:2]):
打印(“您在图像区域外单击了”)
其他:
打印(“您在缩放的矩形“%CoordsInDisplayeImage”中单击了%s)
coordsInFullImage=self.panAndZoomState.ul+CoordsInDisplayeImage
打印(“这是实际图像“%CoordsFullImage”中的%s)
打印(“此像素包含%s,%s%”(self.img[coordsInFullImage[0],coordsInFullImage[1]]))
如果self.onLeftClickFunction不是None:
self.onLeftClickFunction(coordsInFullImage[0],coordsInFullImage[1])
#您可以在此处处理其他鼠标单击事件
def ON VTRACKBARMOVE(自身,勾选位置):
self.panAndZoomState.setYFractionOffset(浮动(滴答声位置)/self.TRACKBAR_滴答声)
def onHTrackbarMove(自身,勾选位置):
self.panAndZoomState.setXFractionOffset(float(tickPosition)/self.TRACKBAR_TICKS)
def重绘图像(自):
pzs=self.panAndZoomState
cv2.imshow(self.WINDOW_NAME,self.img[pzs.ul[0]:pzs.ul[0]+pzs.shape[0]、pzs.ul[1]:pzs.ul[1]+pzs.shape[1])
类PanAndZoomState(对象):
“”“跟踪当前显示的图像矩形。
进行数学运算以将此矩形调整为平移和缩放。”“”
最小形状=np.数组([50,50])
定义初始化(self、imShape、parentWindow):
self.ul=np.array([0,0])#缩放矩形的左上角(表示为y,x)
self.imShape=np.array(imShape[0:2])
self.shape=self.imShape#矩形的当前尺寸
self.parentWindow=父窗口
def缩放(自缩放、相对缩放、相对缩放、缩放因子):
self.shape=(self.shape.astype(np.float)/zoomInFactor.astype(np.int)
#如果可能,将视图扩展为方形。(我不知道如何获得实际的窗口纵横比)
self.shape[:]=np.max(self.shape)
self.shape=np.max(PanAndZoomState.MIN_shape,self.shape)#防止放大过远
c=self.ul+np.array([relativeCy,relativeCx])
self.ul=(c-self.shape/2).astype(np.int)
self.\u fixBoundsAndDraw()
定义固定边界和绘制(自):
“”“确保我们没有在图像外滚动/缩放。
然后绘制当前显示的图像矩形。”“”
#打印(“在self.ul中:%s形状:%s”%(self.ul,self.shape))
self.ul=np.最大值(0,np.最小值(self.ul,self.imShape-self.shape))
self.shape=np.minimum(np.maximum(PanAndZoomState.minu-shape,self.shape),self.imShape-self.ul)
#打印(“输出self.ul:%s形状:%s”%(self.ul,s
def nothing(x):
    pass

# Load image
image = cv2.imread("XXX.jpg")

# Create a window
cv2.namedWindow('image')

# Resize a window

cv2.resizeWindow('image', 1,1)

# Create trackbars for color change
# Hue is from 0-179 for Opencv
cv2.createTrackbar('HMin', 'image', 0, 179, nothing)
cv2.createTrackbar('SMin', 'image', 0, 255, nothing)
cv2.createTrackbar('VMin', 'image', 0, 255, nothing)
cv2.createTrackbar('HMax', 'image', 0, 179, nothing)
cv2.createTrackbar('SMax', 'image', 0, 255, nothing)
cv2.createTrackbar('VMax', 'image', 0, 255, nothing)

# Set default value for Max HSV trackbars
cv2.setTrackbarPos('HMax', 'image', 179)
cv2.setTrackbarPos('SMax', 'image', 255)
cv2.setTrackbarPos('VMax', 'image', 255)

# Initialize HSV min/max values
hMin = sMin = vMin = hMax = sMax = vMax = 0
phMin = psMin = pvMin = phMax = psMax = pvMax = 0


while(1):
    # Get current positions of all trackbars
    hMin = cv2.getTrackbarPos('HMin', 'image')
    sMin = cv2.getTrackbarPos('SMin', 'image')
    vMin = cv2.getTrackbarPos('VMin', 'image')
    hMax = cv2.getTrackbarPos('HMax', 'image')
    sMax = cv2.getTrackbarPos('SMax', 'image')
    vMax = cv2.getTrackbarPos('VMax', 'image')

    # Set minimum and maximum HSV values to display
    lower = np.array([hMin, sMin, vMin])
    upper = np.array([hMax, sMax, vMax])

    # Convert to HSV format and color threshold
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv, lower, upper)
    result = cv2.bitwise_and(image, image, mask=mask)

    # Print if there is a change in HSV value
    if((phMin != hMin) | (psMin != sMin) | (pvMin != vMin) | (phMax != hMax) | (psMax != sMax) | (pvMax != vMax) ):
        print("(hMin = %d , sMin = %d, vMin = %d), (hMax = %d , sMax = %d, vMax = %d)" % (hMin , sMin , vMin, hMax, sMax , vMax))
        phMin = hMin
        psMin = sMin
        pvMin = vMin
        phMax = hMax
        psMax = sMax
        pvMax = vMax

    # Display result image
    cv2.imshow('image', result)
    if cv2.waitKey(10) & 0xFF == ord('q'):
        break
# -*- coding: utf-8 -*-
import cv2
import numpy as np

class PanZoomWindow(object):
    """ Controls an OpenCV window. Registers a mouse listener so that:
        1. right-dragging up/down zooms in/out
        2. right-clicking re-centers
        3. trackbars scroll vertically and horizontally 
    You can open multiple windows at once if you specify different window names.
    You can pass in an onLeftClickFunction, and when the user left-clicks, this 
    will call onLeftClickFunction(y,x), with y,x in original image coordinates."""
    def __init__(self, img, windowName = 'PanZoomWindow', onLeftClickFunction = None):
        self.WINDOW_NAME = windowName
        self.H_TRACKBAR_NAME = 'x'
        self.V_TRACKBAR_NAME = 'y'
        self.img = img
        self.onLeftClickFunction = onLeftClickFunction
        self.TRACKBAR_TICKS = 1000
        self.panAndZoomState = PanAndZoomState(img.shape, self)
        self.lButtonDownLoc = None
        self.mButtonDownLoc = None
        self.rButtonDownLoc = None
        cv2.namedWindow(self.WINDOW_NAME, cv2.WINDOW_NORMAL)
        self.redrawImage()
        cv2.setMouseCallback(self.WINDOW_NAME, self.onMouse)
        cv2.createTrackbar(self.H_TRACKBAR_NAME, self.WINDOW_NAME, 0, self.TRACKBAR_TICKS, self.onHTrackbarMove)
        cv2.createTrackbar(self.V_TRACKBAR_NAME, self.WINDOW_NAME, 0, self.TRACKBAR_TICKS, self.onVTrackbarMove)
    def onMouse(self,event, x,y,_ignore1,_ignore2):
        """ Responds to mouse events within the window. 
        The x and y are pixel coordinates in the image currently being displayed.
        If the user has zoomed in, the image being displayed is a sub-region, so you'll need to
        add self.panAndZoomState.ul to get the coordinates in the full image."""
        if event == cv2.EVENT_MOUSEMOVE:
            return
        elif event == cv2.EVENT_RBUTTONDOWN:
            #record where the user started to right-drag
            self.mButtonDownLoc = np.array([y,x])
        elif event == cv2.EVENT_RBUTTONUP and self.mButtonDownLoc is not None:
            #the user just finished right-dragging
            dy = y - self.mButtonDownLoc[0]
            pixelsPerDoubling = 0.2*self.panAndZoomState.shape[0] #lower = zoom more
            changeFactor = (1.0+abs(dy)/pixelsPerDoubling)
            changeFactor = min(max(1.0,changeFactor),5.0)
            if changeFactor < 1.05:
                dy = 0 #this was a click, not a draw. So don't zoom, just re-center.
            if dy > 0: #moved down, so zoom out.
                zoomInFactor = 1.0/changeFactor
            else:
                zoomInFactor = changeFactor
#            print("zoomFactor: %s"%zoomFactor)
            self.panAndZoomState.zoom(self.mButtonDownLoc[0], self.mButtonDownLoc[1], zoomInFactor)
        elif event == cv2.EVENT_LBUTTONDOWN:
            #the user pressed the left button. 
            coordsInDisplayedImage = np.array([y,x])
            if np.any(coordsInDisplayedImage < 0) or np.any(coordsInDisplayedImage > self.panAndZoomState.shape[:2]):
                print("you clicked outside the image area")
            else:
                print("you clicked on %s within the zoomed rectangle"%coordsInDisplayedImage)
                coordsInFullImage = self.panAndZoomState.ul + coordsInDisplayedImage
                print("this is %s in the actual image"%coordsInFullImage)
                print("this pixel holds %s, %s"%(self.img[coordsInFullImage[0],coordsInFullImage[1]]))
                if self.onLeftClickFunction is not None:
                    self.onLeftClickFunction(coordsInFullImage[0],coordsInFullImage[1])
        #you can handle other mouse click events here
    def onVTrackbarMove(self,tickPosition):
        self.panAndZoomState.setYFractionOffset(float(tickPosition)/self.TRACKBAR_TICKS)
    def onHTrackbarMove(self,tickPosition):
        self.panAndZoomState.setXFractionOffset(float(tickPosition)/self.TRACKBAR_TICKS)
    def redrawImage(self):
        pzs = self.panAndZoomState
        cv2.imshow(self.WINDOW_NAME, self.img[pzs.ul[0]:pzs.ul[0]+pzs.shape[0], pzs.ul[1]:pzs.ul[1]+pzs.shape[1]])

class PanAndZoomState(object):
    """ Tracks the currently-shown rectangle of the image.
    Does the math to adjust this rectangle to pan and zoom."""
    MIN_SHAPE = np.array([50,50])
    def __init__(self, imShape, parentWindow):
        self.ul = np.array([0,0]) #upper left of the zoomed rectangle (expressed as y,x)
        self.imShape = np.array(imShape[0:2])
        self.shape = self.imShape #current dimensions of rectangle
        self.parentWindow = parentWindow
    def zoom(self,relativeCy,relativeCx,zoomInFactor):
        self.shape = (self.shape.astype(np.float)/zoomInFactor).astype(np.int)
        #expands the view to a square shape if possible. (I don't know how to get the actual window aspect ratio)
        self.shape[:] = np.max(self.shape) 
        self.shape = np.maximum(PanAndZoomState.MIN_SHAPE,self.shape) #prevent zooming in too far
        c = self.ul+np.array([relativeCy,relativeCx])
        self.ul = (c-self.shape/2).astype(np.int)
        self._fixBoundsAndDraw()
    def _fixBoundsAndDraw(self):
        """ Ensures we didn't scroll/zoom outside the image. 
        Then draws the currently-shown rectangle of the image."""
#        print("in self.ul: %s shape: %s"%(self.ul,self.shape))
        self.ul = np.maximum(0,np.minimum(self.ul, self.imShape-self.shape))
        self.shape = np.minimum(np.maximum(PanAndZoomState.MIN_SHAPE,self.shape), self.imShape-self.ul)
#        print("out self.ul: %s shape: %s"%(self.ul,self.shape))
        yFraction = float(self.ul[0])/max(1,self.imShape[0]-self.shape[0])
        xFraction = float(self.ul[1])/max(1,self.imShape[1]-self.shape[1])
        cv2.setTrackbarPos(self.parentWindow.H_TRACKBAR_NAME, self.parentWindow.WINDOW_NAME,int(xFraction*self.parentWindow.TRACKBAR_TICKS))
        cv2.setTrackbarPos(self.parentWindow.V_TRACKBAR_NAME, self.parentWindow.WINDOW_NAME,int(yFraction*self.parentWindow.TRACKBAR_TICKS))
        self.parentWindow.redrawImage()
    def setYAbsoluteOffset(self,yPixel):
        self.ul[0] = min(max(0,yPixel), self.imShape[0]-self.shape[0])
        self._fixBoundsAndDraw()
    def setXAbsoluteOffset(self,xPixel):
        self.ul[1] = min(max(0,xPixel), self.imShape[1]-self.shape[1])
        self._fixBoundsAndDraw()
    def setYFractionOffset(self,fraction):
        """ pans so the upper-left zoomed rectange is "fraction" of the way down the image."""
        self.ul[0] = int(round((self.imShape[0]-self.shape[0])*fraction))
        self._fixBoundsAndDraw()
    def setXFractionOffset(self,fraction):
        """ pans so the upper-left zoomed rectange is "fraction" of the way right on the image."""
        self.ul[1] = int(round((self.imShape[1]-self.shape[1])*fraction))
        self._fixBoundsAndDraw()

if __name__ == "__main__":
    infile = "XXX.jpg"
    myImage = cv2.imread(infile,cv2.IMREAD_ANYCOLOR)
    window = PanZoomWindow(myImage, "test window")
    key = -1
    while key != ord('q') and key != 27: # 27 = escape key
        #the OpenCV window won't display until you call cv2.waitKey()
        key = cv2.waitKey(5) #User can press 'q' or ESC to exit.
    cv2.destroyAllWindows()