2

before sometime I wrote some script which find center of the Sun (with Canny and moments) and center of the image. Here is it python opencv-finding circle (Sun) , coordinates of center the circle from picture

But now I have this problem. When I used this script on fits file it doesnt work. I have 16 bit monochromatic picture of the Sun http://files.uloziste.com/d16feb4de5aeda18/.

I know that the picture from my method must be 8 bit (CV_8U)

How I can convert this picture to 8 bit and get image depth information too? When I used height, width, depth = im.shape i get error:

height, width, depth = im.shape ValueError: need more than 2 values to unpack

Here is code for open fits file

import numpy as np
import cv2
import pyfits


hdul = pyfits.open('11_18_46_640_syn_snap_obs_1533.fits')
im=hdul[0].data


#height, width, depth = im.shape
print im.shape
thresh = 123
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)

blur = cv2.GaussianBlur(imgray,(5,5),0)
edges = cv2.Canny(blur,thresh,thresh*2)
contours,hierarchy=cv2.findContours(edges,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
c=len(contours) - 1

cnt = contours[c]
cv2.drawContours(im,contours,-1,(0,255,0),-1)

#centroid_x = M10/M00 and centroid_y = M01/M00
M = cv2.moments(cnt)
x = int(M['m10']/M['m00'])
y = int(M['m01']/M['m00'])
print x,y

cv2.circle(im,(x,y),1,(0,0,255),2)
cv2.putText(im,"x[px],y[px]",(10,50), cv2.FONT_HERSHEY_SIMPLEX, 1,  (255,0,255))
cv2.putText(im,"center of Sun",(x,y), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255))
cv2.putText(im,str(x)+","+str(y),(10,100), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255))
cv2.circle(im,(width/2,height/2),1,(255,0,0),2)
cv2.putText(im,"center of image",(width/2,height/2),    cv2.FONT_HERSHEY_SIMPLEX, 1, (255,0,0))
cv2.putText(im,str(width/2)+","+str(height/2), (10,150),    cv2.FONT_HERSHEY_SIMPLEX, 1, (255,0,0))
cv2.putText(im,"difference:"+str(width/2-x)+","+str(height/2-y),(400,50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,255,255))

cv2.imshow('contour',im)
cv2.waitKey(0) code here

Ok here is edit:

This code convert my picture to 8 bit. But when I run script I get error: cnt = contours[0] IndexError: list index out of range

Why is that? Any suggestion?

Code

import pyfits
import numpy as np
import cv2

hdul = pyfits.open('11_18_46_640_syn_snap_obs_1533.fits')

hdu=hdul[0].data
ma=hdu.max()
mi=hdu.min()
image = np.array(hdu, copy=True)
image.clip(mi,ma, out=image)
image -=mi
image //= (ma - mi + 1) / 255.
im=image.astype(np.uint8)

#height, width, depth = im.shape
#print im.shape


thresh = 123
imgray = cv2.cvtColor(im,cv2.COLOR_GRAY2RGB)

blur = cv2.GaussianBlur(im,(5,5),0)

edges = cv2.Canny(blur,thresh,thresh*2)

contours, hierarchy =cv2.findContours(edges,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

c=len(contours) - 1

cnt = contours[0]
cv2.drawContours(im,contours,-1,(0,255,0),-1)

#centroid_x = M10/M00 and centroid_y = M01/M00
M = cv2.moments(cnt)
x = int(M['m10']/M['m00'])
y = int(M['m01']/M['m00'])

print x,y

cv2.circle(im,(x,y),1,(0,0,255),2)
cv2.putText(im,"x[px],y[px]",(10,50), cv2.FONT_HERSHEY_SIMPLEX, 1,    (255,0,255))
cv2.putText(im,"center of Sun",(x,y), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255))
cv2.putText(im,str(x)+","+str(y),(10,100), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255))
cv2.circle(im,(width/2,height/2),1,(255,0,0),2)
cv2.putText(im,"center of image",(width/2,height/2),       cv2.FONT_HERSHEY_SIMPLEX, 1, (255,0,0))
cv2.putText(im,str(width/2)+","+str(height/2), (10,150), cv2.FONT_HERSHEY_SIMPLEX, 1, (255,0,0))
cv2.putText(im,"difference:"+str(width/2-x)+","+str(height/2-y),(400,50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,255,255))

cv2.imshow('im',im)
cv2.waitKey(0)
Community
  • 1
  • 1
Franta Konopnik
  • 189
  • 2
  • 9
  • 20

1 Answers1

0

Well, your initial problem is with understanding 16-bit file format.
Regular grayscale encodes shade with unsigned 8 bits, thus ranging from 0 to 255. 16-bit image just extends this range, allowing up to 2^16 shades. Therefore it makes no sense to get depth of an image with ndarray.shape - it only has one color channel (i.e. 2-D matrix with single UINT16 value per pixel).

As for the second issue with indexing:
ndarray.astype('uint8') grabs least significant bits, so, let's say 1460 (0101_1011_0100) will become 180 (1011_0100). My guess is that you then try to find contours with Canny in a different picture from what you expect, with no success. Then you are simply indexing an empty array.

Solution
Use cv2.convertScaleAbs(image, alpha=(255/65535)) to convert 16-bit to 8-bit

TheNoneMan
  • 31
  • 3