I have a program that detects laser points that I know works when I read an image from video 0 but I do not know how to make the program work from a ros subscriber image. I need to know how to convert a ros image subscriber into a usable opencv image named "image" I have researched how to do this and I have come across several solutions that all use the function bridge.imgmsg_to_cv2 but I can not get this to work I am sure it is a simple fix I just don't know what I am doing. This should be relatively simple though. here is my code:
# import the necessary packages
from __future__ import print_function
from imutils import contours
from skimage import measure
import numpy as np
import argparse
import imutils
import cv2
import message_filters
from sensor_msgs.msg import Image, CameraInfo
from std_msgs.msg import Int32, Float32MultiArray
import rospy
from cv_bridge import CvBridge, CvBridgeError
import roslib
roslib.load_manifest('my_package')
import sys
import rospy
import cv2
from std_msgs.msg import String
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError
'''
def getPoint(cameraTip,dotXY,normalPoint):
slope= (cameraTip[2]-dotXY[2])/(cameraTip[1]-dotXY[1])
b=cameraTip[2]-(slope*cameraTip[1])
z=slope*normalPoint[1]+b
return [normalPoint[0],normalPoint[1],z]
'''
class image_converter:
def __init__(self):
self.image_pub = rospy.Publisher("image_topic_2",Image)
self.bridge = CvBridge()
self.image_sub = rospy.Subscriber("CM_040GE/image_raw",Image,self.callback)
def callback(self,data):
try:
cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
except CvBridgeError as e:
print(e)
(rows,cols,channels) = cv_image.shape
if cols > 60 and rows > 60 :
cv2.circle(cv_image, (50,50), 10, 255)
cv2.imshow("Image window", cv_image)
cv2.waitKey(3)
try:
self.image_pub.publish(self.bridge.cv2_to_imgmsg(cv_image, "bgr8"))
except CvBridgeError as e:
print(e)
def main(args):
ic = image_converter()
rospy.init_node('image_converter', anonymous=True)
try:
rospy.spin()
except KeyboardInterrupt:
print("Shutting down")
cv2.destroyAllWindows()
if __name__ == '__main__':
main(sys.argv)
image = bridge.imgmsg_to_cv2(image_message, desired_encoding="passthrough")
while(1):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (11, 11), 0)
#threshold the image to reveal light regions in the
# blurred image
thresh = cv2.threshold(blurred, 30, 255, cv2.THRESH_BINARY)[1]
# perform a series of erosions and dilations to remove
# any small blobs of noise from the thresholded image
thresh = cv2.erode(thresh, None, iterations=2)
thresh = cv2.dilate(thresh, None, iterations=4)
# perform a connected component analysis on the thresholded
# image, then initialize a mask to store only the "large"
# components
labels = measure.label(thresh, neighbors=8, background=0)
mask = np.zeros(thresh.shape, dtype="uint8")
# loop over the unique components
for label in np.unique(labels):
# if this is the background label, ignore it
if label == 0:
continue
# otherwise, construct the label mask and count the
# number of pixels
labelMask = np.zeros(thresh.shape, dtype="uint8")
labelMask[labels == label] = 255
numPixels = cv2.countNonZero(labelMask)
# if the number of pixels in the component is sufficiently
# large, then add it to our mask of "large blobs"
if numPixels > 300:
mask = cv2.add(mask, labelMask)
# find the contours in the mask, then sort them from left to
# right
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
cnts = contours.sort_contours(cnts)[0]
# loop over the contours
for (i, c) in enumerate(cnts):
# draw the bright spot on the image
(x, y, w, h) = cv2.boundingRect(c)
((cX, cY), radius) = cv2.minEnclosingCircle(c)
#x and y center are cX and cY
cv2.circle(image, (int(cX), int(cY)), int(radius),
(0, 0, 255), 3)
cv2.putText(image, "#{}".format(i + 1), (x, y - 15),
cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2)
# show the output image
cv2.imshow("Image", image)
cv2.waitKey(1)
#camera.release()
Currently the error I am getting is:
Traceback (most recent call last):
File "lazerSub2.py", line 18, in <module>
roslib.load_manifest('my_package')
File "/opt/ros/indigo/lib/python2.7/dist-packages/roslib/launcher.py", line 62, in load_manifest
sys.path = _generate_python_path(package_name, _rospack) + sys.path
File "/opt/ros/indigo/lib/python2.7/dist-packages/roslib/launcher.py", line 93, in _generate_python_path
m = rospack.get_manifest(pkg)
File "/usr/lib/python2.7/dist-packages/rospkg/rospack.py", line 167, in get_manifest
return self._load_manifest(name)
File "/usr/lib/python2.7/dist-packages/rospkg/rospack.py", line 211, in _load_manifest
retval = self._manifests[name] = parse_manifest_file(self.get_path(name), self._manifest_name, rospack=self)
File "/usr/lib/python2.7/dist-packages/rospkg/rospack.py", line 203, in get_path
raise ResourceNotFound(name, ros_paths=self._ros_paths)
rospkg.common.ResourceNotFound: my_package
ROS path [0]=/opt/ros/indigo/share/ros
ROS path [1]=/home/robot/catkin_ws/src
ROS path [2]=/opt/ros/indigo/share
ROS path [3]=/opt/ros/indigo/stacks
I think this is what you wanted to do, separate out the ros and the cv components. Your first error was when you were mixing the ros types badly with cv processing. If you throw the ros stuff into a main/main class, keep all of the ros types there, and your functional processing elsewhere.
''' image_converter.py '''
from __future__ import print_function
import cv2
import numpy as np
import imutils
from imutils import contours
from skimage import measure
'''
def getPoint(cameraTip,dotXY,normalPoint):
slope= (cameraTip[2]-dotXY[2])/(cameraTip[1]-dotXY[1])
b=cameraTip[2]-(slope*cameraTip[1])
z=slope*normalPoint[1]+b
return [normalPoint[0],normalPoint[1],z]
'''
# Image Processing functions
def convert_image(image): # Image of kind bgr8
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (11, 11), 0)
#threshold the image to reveal light regions in the
# blurred image
thresh = cv2.threshold(blurred, 30, 255, cv2.THRESH_BINARY)[1]
# perform a series of erosions and dilations to remove
# any small blobs of noise from the thresholded image
thresh = cv2.erode(thresh, None, iterations=2)
thresh = cv2.dilate(thresh, None, iterations=4)
# perform a connected component analysis on the thresholded
# image, then initialize a mask to store only the "large"
# components
labels = measure.label(thresh, neighbors=8, background=0)
mask = np.zeros(thresh.shape, dtype="uint8")
# loop over the unique components
for label in np.unique(labels):
# if this is the background label, ignore it
if label == 0:
continue
# otherwise, construct the label mask and count the
# number of pixels
labelMask = np.zeros(thresh.shape, dtype="uint8")
labelMask[labels == label] = 255
numPixels = cv2.countNonZero(labelMask)
# if the number of pixels in the component is sufficiently
# large, then add it to our mask of "large blobs"
if numPixels > 300:
mask = cv2.add(mask, labelMask)
# find the contours in the mask, then sort them from left to
# right
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
cnts = contours.sort_contours(cnts)[0]
# loop over the contours
for (i, c) in enumerate(cnts):
# draw the bright spot on the image
(x, y, w, h) = cv2.boundingRect(c)
((cX, cY), radius) = cv2.minEnclosingCircle(c)
#x and y center are cX and cY
cv2.circle(image, (int(cX), int(cY)), int(radius),
(0, 0, 255), 3)
cv2.putText(image, "#{}".format(i + 1), (x, y - 15),
cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2)
# show the output image
cv2.imshow("Image", image)
cv2.waitKey(1)
#camera.release()
return image
# ROS Interface
if __name__ == "__main__":
import rospy
from cv_bridge import CvBridge, CvBridgeError
from sensor_msgs.msg import Image
bridge = CvBridge()
def show_img(cv_image):
(rows,cols,channels) = cv_image.shape
if cols > 60 and rows > 60 :
cv2.circle(cv_image, (50,50), 10, 255)
cv2.imshow("Image window", cv_image)
cv2.waitKey(3)
image_pub = rospy.Publisher("image_topic_2", Image)
def callback(data):
try:
cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
show_img(cv_image)
cv_image2 = convert_image(cv_image)
image_pub.publish(bridge.cv2_to_imgmsg(cv_image2, "bgr8"))
except CvBridgeError as e:
print(e)
image_sub = rospy.Subscriber("CM_040GE/image_raw", Image, callback)
rospy.init_node('image_converter', anonymous=True)
rospy.spin()
print("image_converter: Shutting down")
cv2.destroyAllWindows()
Related
I would like to find the intersection between my mask that it's like this:
And the textured image:
I wanted something like this, but without the blue line (it's just to see more the difference) and without the info in the borders:
Thanks!!!!
EDIT: That's my code by now:
from PIL import Image
import os
from PIL import Image, ImageFont, ImageDraw
import numpy as np
import cv2
import cv
import matplotlib.pyplot as plt
from scipy.misc import derivative
import copy
import skimage.feature.texture
from PIL import Image
class TextureWavelets:
def access_to_images(self, directory_segmentation: str, directory_originals: str, n_displays: int,
color_plaque: str):
count = 0
for image_name in os.listdir(directory_originals):
if count < n_displays:
segmented_image = cv2.imread(directory_segmentation + "/" + image_name)
segmented = Image.open(directory_segmentation + "/" + image_name)
original = Image.open(directory_originals + "/" + image_name)
masked = self.create_mask_plaque(segmented_image, color_plaque)
intersection = self.find_intersection(segmented_image, masked)
haralick = self.haralick(segmented_image, 'contrast')
def find_intersection(self, mask, image):
mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
masked_image = image * mask
Image.fromarray(masked_image).show()
def create_mask_plaque(self, image, color_plaque):
COLOR1_RANGE = [(30, 0, 0), (255, 50, 50)] # Blue in BGR, [(low), (high)].
if color_plaque == 'green':
COLOR1_RANGE = [(0, 30, 0), (50, 255, 50)]
elif color_plaque == 'red':
COLOR1_RANGE = [(0, 0, 30), (50, 50, 255)]
elif color_plaque == 'blue':
COLOR1_RANGE = [(30, 0, 0), (255, 50, 50)]
elif color_plaque == 'b&w':
COLOR1_RANGE = [(0, 0, 255), (255, 255, 255)]
mask = cv2.inRange(image, COLOR1_RANGE[0], COLOR1_RANGE[1])
only_plaque = cv2.bitwise_and(image, image, mask=mask)
gray = cv2.cvtColor(only_plaque, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3, 3), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
thresh = 255 - thresh
# Morph open with a elliptical shaped kernel
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)
Image.fromarray(opening).show()
return opening
def haralick(self, image, function):
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
P = skimage.feature.texture.greycomatrix(image, [1], [0], levels=256, symmetric=False, normed=False)
result = skimage.feature.texture.greycoprops(P, prop=function)
return result[0][0]
if __name__ == "__main__":
texture_wavelets = TextureWavelets()
directory_segmentation = 'D:/CTU/new_segmentation_data/references/trans'
directory_originals = 'D:/CTU/new_segmentation_data/data/trans'
n_displays = 2
# options for lumen and plaque colors: green, red, blue, b&w
texture_wavelets.access_to_images(directory_segmentation, directory_originals, n_displays, 'b&w')
The problem is that the find_intersection function returns me this:
It's gray with no texture, and what I need is the texture...
Here is how I would do it:
import cv2
import numpy as np
img = cv2.imread("ring_bg.png")
mask = cv2.imread("ring_mask.png")
h, w, _ = img.shape
mask = cv2.resize(cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY), (w, h)) # Resize image
bg = np.zeros_like(img, 'uint8') # Black background
def crop(img, bg, mask):
fg = cv2.bitwise_or(img, img, mask=mask)
fg_back_inv = cv2.bitwise_or(bg, bg, mask=cv2.bitwise_not(mask))
return cv2.bitwise_or(fg, fg_back_inv)
cv2.imshow("Image", crop(img, bg, mask))
cv2.waitKey(0)
Output:
I used below code for find cigarettes count in the below image using opencv python, but its not worked. Only this code finding some places only. i don't know what is the issue.. please help me
import numpy as np
import cv2
from PIL import Image
import sys
Path='D:\Artificial intelligence\Phyton'
filename='Test.png'
img = cv2.imread('D:\Artificial intelligence\Phyton\Test.png')
img1 = cv2.imread('D:\Artificial intelligence\Phyton\Test.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY)
img[thresh == 255] = 0
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
erosion = cv2.erode(img, kernel, iterations = 1)
cv2.imwrite('D:\Artificial intelligence\Phyton\Test112.png',erosion)
def findcircles(img,contours):
minArea = 300;
minCircleRatio = 0.5;
for contour in contours:
(x,y),radius = cv2.minEnclosingCircle(contour)
center = (int(x),int(y))
radius = int(radius)
if radius > 5:
continue;
cv2.circle(img1, center, 1, (191, 255, 0), 2)
cv2.imwrite('D:\Artificial intelligence\Phyton\Test11234.png',img1)
img = cv2.imread("D:\Artificial intelligence\Phyton\Test112.png")
cv2.imwrite('D:\Artificial intelligence\Phyton\org.png',img)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,threshold = cv2.threshold(gray, 199, 255,cv2.THRESH_BINARY_INV)
cv2.imwrite('D:\Artificial intelligence\Phyton\threshold.png',threshold)
blur = cv2.medianBlur(gray,7)
cv2.imwrite('D:\Artificial intelligence\Phyton\blur.png',blur)
laplacian=cv2.Laplacian(blur,-1,ksize = 5,delta = -50)
cv2.imwrite('D:\Artificial intelligence\Phyton\laplacian.png',laplacian)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(7,7))
dilation = cv2.dilate(laplacian,kernel,iterations = 1)
cv2.imwrite('D:\Artificial intelligence\Phyton\dilation.png',dilation)
result= cv2.subtract(threshold,dilation)
cv2.imwrite('D:\Artificial intelligence\Phyton\result.png',result)
contours, hierarchy = cv2.findContours(result,cv2.RETR_LIST,cv2.CHAIN_APPROX_NONE)
findcircles(gray,contours)
Image :
enter image description here
My result:
enter image description here
am using hough transform for detecting circles in the real time video frame.in hough circles function the first parameter is to pass as an single channel image.i dont know how to do this. it continously shows error in that part.
the code am using :
import cv2
import cv2 as cv
from matplotlib import pyplot as plt
from scipy.ndimage import imread
import numpy as np
fgbg = cv2.bgsegm.createBackgroundSubtractorMOG()
cam_capture = cv2.VideoCapture(0)
cv2.destroyAllWindows()
upper_left = (50, 50)
bottom_right = (300, 300)
def sketch_transform(image):
## print(image)
## print("2")
## #gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
## print(image)
## print("3")
## gray = 255-gray
## ret, thresh = cv2.threshold(gray, 225, 255, cv2.THRESH_BINARY_INV)
## image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
## print(image)
## print("4")
## #image = cv2.drawContours(image, contours, -1,(0,0,255),3)
## print(image)
## print("4")
circle_detect(image)
return image
def circle_detect(image):
#image1=str(image)
#mage = cv2.imread(image, cv2.IMREAD_COLOR)
print (image)
print("k")
image = cv2.cvtColor(image,cv2.COLOR_GRAY2RGB)
circles = cv2.HoughCircles(image,cv2.HOUGH_GRADIENT,1,20,
param1=90,param2=30,minRadius=0,maxRadius=100)
print(circles)
circles = np.uint16(np.around(circles))
## for i in circles[0,:]:
## # draw the outer circle
## cv2.circle(image,(i[0],i[1]),i[2],(0,255,0),2)
## # draw the center of the circle
## cv2.circle(image,(i[0],i[1]),2,(0,0,255),3)
return circles
while True:
_, image_frame = cam_capture.read()
#Rectangle marker
r = cv2.rectangle(image_frame, upper_left, bottom_right, (100, 50, 200), 5)
rect_img = image_frame[upper_left[1] : bottom_right[1], upper_left[0] : bottom_right[0]]
sketcher_rect = rect_img
print(sketcher_rect)
print("1")
sketcher_rect = sketch_transform(sketcher_rect)
#Conversion for 3 channels to put back on original image (streaming)
#sketcher_rect_rgb = cv2.cvtColor(sketcher_rect, cv2.COLOR_GRAY2RGB)
#Replacing the sketched image on Region of Interest
image_frame[upper_left[1] : bottom_right[1], upper_left[0] : bottom_right[0]] = sketcher_rect
cv2.imshow("Sketcher ROI", image_frame)
if cv2.waitKey(1) == 13:
break
cam_capture.release()
cv2.destroyAllWindows()
am new to opencv and i have been struggling for last four days for detecting circles in a video frame.as an image the detction is good but it make some trouble in video frame.
the output is:
Traceback (most recent call last):
File "/home/pi/Downloads/Pi-tracker-master/fgroi.py", line 62, in <module>
sketcher_rect = sketch_transform(sketcher_rect)
File "/home/pi/Downloads/Pi-tracker-master/fgroi.py", line 27, in sketch_transform
circle_detect(image)
File "/home/pi/Downloads/Pi-tracker-master/fgroi.py", line 36, in circle_detect
image = cv2.cvtColor(image,cv2.COLOR_GRAY2RGB)
cv2.error: OpenCV(3.4.4) /home/pi/packaging/opencv-python/opencv/modules/imgproc/src/color.hpp:255: error: (-2:Unspecified error) in function 'cv::CvtHelper<VScn, VDcn, VDepth, sizePolicy>::CvtHelper(cv::InputArray, cv::OutputArray, int) [with VScn = cv::Set<1>; VDcn = cv::Set<3, 4>; VDepth = cv::Set<0, 2, 5>; cv::SizePolicy sizePolicy = (cv::SizePolicy)2u; cv::InputArray = const cv::_InputArray&; cv::OutputArray = const cv::_OutputArray&]'
> Invalid number of channels in input image:
> 'VScn::contains(scn)'
> where
> 'scn' is 3
I am trying to select the image corner's and crop it and then perform perspective transform on it.
but when I run this code, the window with an image opens up, but on double click, nothing happens so that I with double click, I could select image corners.
here's my code
from transform import four_point_transform
import imutils
from skimage.filters import threshold_adaptive
import numpy as np
import cv2
image = cv2.imread("test1.jpg")
ratio = image.shape[0] / 500.0
orig = image.copy()
window_name = "Select corner points of object"
cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)
cv2.imshow(window_name, image)
pts_1 = []
def callback(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDBLCLK:
pts_1.append((x, y))
cv2.circle(image,(x,y),10,(0,255,0),5)
cv2.imshow(window_name, image)
if(len(pts_1)==4):
pts = np.array(pts_1,dtype="float32")
print(pts_1)
warped = four_point_transform(orig, pts)
warped = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)
warped = threshold_adaptive(warped, 251, offset = 10)
warped = warped.astype("uint8") * 255
cv2.imshow("Original", imutils.resize(orig, height = 650))
cv2.imshow("Scanned", imutils.resize(warped, height = 650))
cv2.waitKey(0)
cv2.setMouseCallback(window_name, callback)
key = cv2.waitKey(0)
Any help would be appreciated?
Opencv with Python!
I am trying to create bounding boxes across objects in a video. I have already used the background subtraction function. I am using finContour function. Now the code detects the edges of the 'bus' in the video and creates a bounding box, but it also detects the edges of the windows of the bus and creates a bonding box for each of the window. I just need to get a bounding box across the bus only.
import numpy as np
import cv2
cap = cv2.VideoCapture("C:\\Python27\\clip1.avi")
fgbg = cv2.BackgroundSubtractorMOG()
while(1):
ret, frame = cap.read()
fgmask = fgbg.apply(frame)
# res,thresh = cv2.threshold(fgmask,127,255,0)
kernel = np.ones((10,10),np.uint8)
dilation = cv2.dilate(fgmask,kernel,iterations = 1)
erosion = cv2.erode(fgmask,kernel,iterations = 1)
contours,hierarchy = cv2.findContours(fgmask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
for i in range(0, len(contours)):
if (i % 1 == 0):
cnt = contours[i]
x,y,w,h = cv2.boundingRect(cnt)
cv2.drawContours(fgmask ,contours, -1, (255,255,0), 3)
cv2.rectangle(fgmask,(x,y),(x+w,y+h),(255,0,0),2)
cv2.imshow('frame',fgmask)
cv2.imshow("original",frame)
if cv2.waitKey(30) == ord('a'):
break
cap.release()
cv2.destroyAllWindows()
import cv2
import numpy as np
#img.png is the fgmask
img=cv2.imread('img.png')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,th1 = cv2.threshold(gray,25,255,cv2.THRESH_BINARY)
_,contours,hierarchy = cv2.findContours(th1, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
x,y,w,h = cv2.boundingRect(cnt)
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
cv2.imshow('image1',img)
cv2.waitKey(0)
cv2.destoryAllWindows(0)
RESULTS