1

I am trying to detect the color at the center of the detected circle from HoughCircles. The way I am doing this is as follows:

print("Center of the circle: ", i[0]," ", i[1])
print(ci[i[0]][i[1]][0]," blue")
print(ci[i[0]][i[1]][1]," green")
print(ci[i[0]][i[1]][2]," red")

Here ci is the opencv image array and i[0] and i[1] represent the center coordinates of the circle as given by HoughCircles in the code given below.

But as I do this, I get an error saying.

IndexError: index 1034 is out of bounds for axis 0 with size 600

I could not understand the reason for this. I am trying to detect the color at the center of the circle.

    import cv2
    import numpy as np
    import sys
    import math


    img = cv2.imread("images/diffc.jpeg", 0)
    ci = cv2.imread("images/diffc.jpeg")

    cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)



    minDist = 150
    param1 = 120
    param2 = 37

    minRadius = 120
    maxRadius = 140


    circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,minDist,
                                param1=param1,param2=param2,minRadius=minRadius,maxRadius=maxRadius)


    if circles is None:
            print("No circles detected!")
            sys.exit(-1)


    circles = np.uint16(np.around(circles))

    for i in circles[0,:]:

        # draw the outer circle
        cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2)
        # draw the center of the circle
        cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3)
        print("Center of the circle: ", i[0]," ", i[1])
        # STATEMENTS THAT THROW ERROR
        print(ci[i[0]][i[1]][0]," blue")
        print(ci[i[0]][i[1]][1]," green")
        print(ci[i[0]][i[1]][2]," red")

    cv2.imshow('detected circles',cimg)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

Here is the image: Image

giannete
  • 13
  • 5

1 Answers1

0

Here You need to know that HoughCircles method returns the center of the circle in the form of width x height and numpy find the image with rows x columns.

So you need to pass first columns and then rows in the ci.

So to detect blue color: ci[i[1]][i[0]][0].

Your final code is:

import cv2
import numpy as np
import sys
import math


img = cv2.imread("images/diffc.jpeg", 0)
ci = cv2.imread("images/diffc.jpeg")

cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)



minDist = 150
param1 = 120
param2 = 37

minRadius = 120
maxRadius = 140


circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,minDist,
                          param1=param1,param2=param2,minRadius=minRadius,maxRadius=maxRadius)


if circles is None:
      print("No circles detected!")
      sys.exit(-1)


circles = np.uint16(np.around(circles))

for i in circles[0,:]:

  # draw the outer circle
  cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2)
  # draw the center of the circle
  cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3)
  print("Center of the circle: ", i[0]," ", i[1])
  # STATEMENTS THAT THROW ERROR
  print(ci[i[1]][i[0]][0]," blue")
  print(ci[i[1]][i[0]][1]," green")
  print(ci[i[1]][i[0]][2]," red")

cv2.imshow('detected circles',cimg)
cv2.waitKey(0)
cv2.destroyAllWindows()
patelnisheet
  • 124
  • 1
  • 3
  • 12
  • Can you please explain it better? I did not understand the relation between width, height and row,columns. – giannete Jan 27 '19 at 06:03
  • image **width** shows the total **columns** in the array and image **height** shows the total **rows** in the array. Here Your Image **width** is `1279` and **height** is `959`. But **numpy** array see it as the `959 rows` and `1279 columns`. – patelnisheet Jan 27 '19 at 06:07
  • Okay. Based on the colors received from each channel, is there a way I could find which circle is most illuminated assuming the color distribution for a particular circle is constant. – giannete Jan 27 '19 at 06:14
  • Convert your image in **HSL image** and detect **L channel** as per your requirement of **Illumination**. – patelnisheet Jan 27 '19 at 06:19
  • To confirm, `i[0]` denotes the x-coordinate and `i[1]` denotes the y-coordinate in the `for i in circles[0,:]` for loop? – giannete Jan 27 '19 at 06:24
  • Yes, But in the form of image `width x height`. But if you want to extract pixel of the image then you should pass image **rows** mean **y-coordinate** first then **column** mean **x-coordinate**. – patelnisheet Jan 27 '19 at 06:28
  • Could you share an example where I could check which color is more illuminated? – giannete Jan 27 '19 at 06:41
  • I read this post https://stackoverflow.com/questions/48182791/how-do-you-lightness-thresh-hold-with-hsl-on-opencv but could not understand it. I want to know which circle is most illuminated amongst the circles of different colors. – giannete Jan 27 '19 at 06:44
  • I think [stack overflow] (https://stackoverflow.com/questions/48182791/how-do-you-lightness-thresh-hold-with-hsl-on-opencv) question will help you to find illumination. – patelnisheet Jan 27 '19 at 06:45
  • okay you read that Example. In your Example you should get all center pixel **L channel** values then you need to select **max** among them. – patelnisheet Jan 27 '19 at 06:49
  • I did this but I do not think the results are correct. The results: https://ibb.co/SvTbxZg where the original image is https://ibb.co/qpJ1v9w The third coordinate is the `L` value – giannete Jan 27 '19 at 07:02
  • 1
    To print `L` value I converted the image into HLS using `hls = cv2.cvtColor(ci, cv2.COLOR_BGR2HLS)` and then placed `L` value using `hls[i[1]][i[0]][1]` – giannete Jan 27 '19 at 07:05
  • Is it that the higher value of lightness would mean less luminous ? Then the results look okay. – giannete Jan 27 '19 at 07:07
  • Here is the image https://ibb.co/SvTbxZg and I calculated the lightness using `hls[i[1]][i[0]][1]` The third coordinate is the `L` assuming it is written as `hls[i[1]][i[0]][1]` – giannete Jan 27 '19 at 07:21
  • Sorry I can't explain you whole program here in comment. I think you should know first how color conversion work in [opencv](https://docs.opencv.org/3.1.0/de/d25/imgproc_color_conversions.html) first. – patelnisheet Jan 27 '19 at 07:25
  • As a suggestion for future answers, I would recommend unpacking ambiguous tuples/lists into named variables and using clearer named variables, i.e. `for circle in circles` and `x, y = circle` instead of `(i[0], i[1])`, just so that others can understand the answer more fluently. – alkasm Jan 27 '19 at 08:54
  • @giannete Not at all. Just read opencv Color conversion documentation. – patelnisheet Jan 27 '19 at 08:57
  • @Alexander Reynolds Okay, Thnx for your suggestion. – patelnisheet Jan 27 '19 at 08:59