0

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 :)

4 Answers 4

2

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)
Sign up to request clarification or add additional context in comments.

Comments

0

Because pt1 is a tuple and doesn't have x or y attributes . You probably want:

pt2 = (pt1[0] + 5, pt1[1] + 5)

Comments

0

You are trying to access an x attribute in pt1, but pt1 is a tuple and tuple have no x attribute. You could either

The second solution could look like the following:

from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p1 = Point(i,j)
p2 = (pt1.x+5,pt1.y+5) 

Comments

0

You can't access plain tuples like that, you need to change

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

to

pt2=(pt1[0] + 5, pt1[0] + 5)

However, Python does have a namedtuple which can be accessed via attributes; there's even a Point namedtuple example in the docs.

Here's a small example derived from the docs I linked to:

#!/usr/bin/env python

from collections import namedtuple

Point = namedtuple('Point', ['x', 'y'])

p = Point(11, y=22)     # instantiate with positional or keyword arguments

print p[0] + p[1]       # indexable like the plain tuple (11, 22)

x, y = p                # unpack like a regular tuple
print x, y
print p.x + p.y         # fields also accessible by name

print repr(p)           # readable __repr__ with a name=value style
print tuple(p)

output

33
11 22
33
Point(x=11, y=22)
(11, 22)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.