Search code examples
pythonopencvcomputer-visiontuplestraceback

'tuple' has no attribute. OpenCV Python


I am trying to pass a window over an image so I can get the average b,g,r pixel values inside the window (not really sure how to do this).

At the moment I am trying to get a window to pass over my image but on line 17 I get the error:

Traceback (most recent call last):
  File "C:\Python27\bgr.py", line 17, in <module>
    pt2=(pt1.x+5,pt1.y+5)
AttributeError: 'tuple' object has no attribute 'x'

Any ideas?

Here is my code:

# import packages
import numpy as np
import argparse
import cv2
import dateutil
from matplotlib import pyplot as plt

bgr_img = cv2.imread('images/0021.jpg')
height, width = bgr_img.shape[:2]

#split b,g,r channels
#b,g,r = cv2.split(bgr_img)

for i in range(0,height):
  for j in range(0,width):
    pt1=(i,j)
    pt2=(pt1.x+5,pt1.y+5)
    point.append([pt1,pt2])
    cv2.rectangle(bgr_img,pt1,pt2,(255,0,0))

#cv2.imshow('image',bgr_img)          
#cv2.waitKey(0)

Thanks in advance :)


Solution

  • This line:

    pt1 = (i, j)  # I have added spaces per the style guide
    

    assigns a new tuple object to the name pt1 (see the docs, the tutorial). Tuples do not, by default, have an x or y attribute. You either need to access the first and second items in the tuple by index:

    pt2 = (pt1[0] + 5, pt1[1] + 5)  # note 0-based indexing
    

    or to create a collections.namedtuple, which allows you to define attributes:

    from collections import namedtuple
    
    Point = namedtuple("Point", "x y")
    
    pt1 = Point(i, j)
    pt2 = Point(pt1.x + 5, pt1.y + 5)
    

    That being said, as i and j are still in scope, the easiest thing to do would be simply:

    pt1 = (i, j)
    pt2 = (i + 5, j + 5)
    

    and even if they weren't still in scope you could unpack pt1 (whether tuple or namedtuple), and use the separate x and y:

    x, y = pt1
    pt2 = (x + 5, y + 5)