How to Get the Position and Draw Rectangle Using Opencv

How to draw a rectangle around a region of interest in python

please don't try with the old cv module, use cv2:

import cv2

cv2.rectangle(img, (x1, y1), (x2, y2), (255,0,0), 2)

x1,y1 ------
| |
| |
| |
--------x2,y2

[edit] to append the follow-up questions below:

cv2.imwrite("my.png",img)

cv2.imshow("lalala", img)
k = cv2.waitKey(0) # 0==wait forever

Python OpenCV cv2 drawing rectangle with text

You can use cv2.putText() to overlay text information on top of a rectangle. For example, you can grab the contour coordinates, draw a rectangle, and put text on top of it by shifting it upwards.

x,y,w,h = cv2.boundingRect(contour)
image = cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 1)
cv2.putText(image, 'Fedex', (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (36,255,12), 2)

You will get something like this

Sample Image

drawing rectangle in openCV python

When you move the mouse during event == cv2.EVENT_MOUSEMOVE you also drawing the recatngle at the same time cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),1).

Try following piece of code.

import cv2
import numpy as np

drawing = False # true if mouse is pressed
mode = True # if True, draw rectangle.
ix,iy = -1,-1

# mouse callback function
def draw_circle(event,x,y,flags,param):
global ix,iy,drawing,mode

if event == cv2.EVENT_LBUTTONDOWN:
drawing = True
ix,iy = x,y

elif event == cv2.EVENT_MOUSEMOVE:
if drawing == True:
if mode == True:
cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),3)
a=x
b=y
if a != x | b != y:
cv2.rectangle(img,(ix,iy),(x,y),(0,0,0),-1)
else:
cv2.circle(img,(x,y),5,(0,0,255),-1)

elif event == cv2.EVENT_LBUTTONUP:
drawing = False
if mode == True:
cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),2)

else:
cv2.circle(img,(x,y),5,(0,0,255),-1)

img = np.zeros((512,512,3), np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle)

while(1):
cv2.imshow('image',img)
k = cv2.waitKey(1) & 0xFF
if k == ord('m'):
mode = not mode
elif k == 27:
break

cv2.destroyAllWindows()

Hope it'll solve your problem. Cheers.

Expected Output:

Rectangle Unfilled Draw


Update


Above piece of code will work only black background image. But we can draw rectangle to any images so -

Try following piece of code.

# import the necessary packages
import cv2
import argparse

# now let's initialize the list of reference point
ref_point = []

def shape_selection(event, x, y, flags, param):
# grab references to the global variables
global ref_point, crop

# if the left mouse button was clicked, record the starting
# (x, y) coordinates and indicate that cropping is being performed
if event == cv2.EVENT_LBUTTONDOWN:
ref_point = [(x, y)]

# check to see if the left mouse button was released
elif event == cv2.EVENT_LBUTTONUP:
# record the ending (x, y) coordinates and indicate that
# the cropping operation is finished
ref_point.append((x, y))

# draw a rectangle around the region of interest
cv2.rectangle(image, ref_point[0], ref_point[1], (0, 255, 0), 2)
cv2.imshow("image", image)

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help="Path to the image")
args = vars(ap.parse_args())

# load the image, clone it, and setup the mouse callback function
image = cv2.imread(args["image"])
clone = image.copy()
cv2.namedWindow("image")
cv2.setMouseCallback("image", shape_selection)

# keep looping until the 'q' key is pressed
while True:
# display the image and wait for a keypress
cv2.imshow("image", image)
key = cv2.waitKey(1) & 0xFF

# press 'r' to reset the window
if key == ord("r"):
image = clone.copy()

# if the 'c' key is pressed, break from the loop
elif key == ord("c"):
break

# close all open windows
cv2.destroyAllWindows()


Save the file as capture_events.py and for testing we selected a demo picture which located at the same directory. Now run the code by following -

python capture_events.py --image demo.jpg

Expected Output:

Sample Image

If some reason we want to re select any portion of the image , we can simply press 'r' to get rid of the bad selection to try a new one.

Hope , it'll will help more. Check this gist, you can implement more functionality on this. Cheers.

opencv draw rectangle function behaves different in C++ , python

I came to conclusion that, cv::Rectangle function takes , offset values for width and height arguments , so suppose

rect = cv::Rect(x,y,w_offset,h_offset)
cv::rectangle(img, rect, cv::Scalar(0x27, 0xC1, 0x36), 2);

c++ implementation for cv::rectangle function internally manages offset values with there respective ending (x,y) bounding box coordinates, but for python based implementation offset values needs to be explicitly sum up with starting (x,y) values of the bounding boxes,

c1, c2 = (x ,y), ((x+w_offset), (y+h_offset))
cv2.rectangle(img, c1, c2, (0, 255, 0), thickness=2, lineType=cv2.LINE_AA)

Drawing rectangle or line using mouse events in open cv using python

You can refer below C++ code which I used to crop image

#include <iostream>
#include "opencv2/opencv.hpp"
#include <stdio.h>

using namespace std;
using namespace cv;

Mat src,img,ROI;
Rect cropRect(0,0,0,0);
Point P1(0,0);
Point P2(0,0);

const char* winName="Crop Image";
bool clicked=false;
int i=0;
char imgName[15];

void checkBoundary(){
//check croping rectangle exceed image boundary
if(cropRect.width>img.cols-cropRect.x)
cropRect.width=img.cols-cropRect.x;

if(cropRect.height>img.rows-cropRect.y)
cropRect.height=img.rows-cropRect.y;

if(cropRect.x<0)
cropRect.x=0;

if(cropRect.y<0)
cropRect.height=0;
}

void showImage(){
img=src.clone();
checkBoundary();
if(cropRect.width>0&&cropRect.height>0){
ROI=src(cropRect);
imshow("cropped",ROI);
}

rectangle(img, cropRect, Scalar(0,255,0), 1, 8, 0 );
imshow(winName,img);
}

void onMouse( int event, int x, int y, int f, void* ){

switch(event){

case CV_EVENT_LBUTTONDOWN :
clicked=true;

P1.x=x;
P1.y=y;
P2.x=x;
P2.y=y;
break;

case CV_EVENT_LBUTTONUP :
P2.x=x;
P2.y=y;
clicked=false;
break;

case CV_EVENT_MOUSEMOVE :
if(clicked){
P2.x=x;
P2.y=y;
}
break;

default : break;

}

if(clicked){
if(P1.x>P2.x){ cropRect.x=P2.x;
cropRect.width=P1.x-P2.x; }
else { cropRect.x=P1.x;
cropRect.width=P2.x-P1.x; }

if(P1.y>P2.y){ cropRect.y=P2.y;
cropRect.height=P1.y-P2.y; }
else { cropRect.y=P1.y;
cropRect.height=P2.y-P1.y; }

}

showImage();

}
int main()
{

cout<<"Click and drag for Selection"<<endl<<endl;
cout<<"------> Press 's' to save"<<endl<<endl;

cout<<"------> Press '8' to move up"<<endl;
cout<<"------> Press '2' to move down"<<endl;
cout<<"------> Press '6' to move right"<<endl;
cout<<"------> Press '4' to move left"<<endl<<endl;

cout<<"------> Press 'w' increas top"<<endl;
cout<<"------> Press 'x' increas bottom"<<endl;
cout<<"------> Press 'd' increas right"<<endl;
cout<<"------> Press 'a' increas left"<<endl<<endl;

cout<<"------> Press 't' decrease top"<<endl;
cout<<"------> Press 'b' decrease bottom"<<endl;
cout<<"------> Press 'h' decrease right"<<endl;
cout<<"------> Press 'f' decrease left"<<endl<<endl;

cout<<"------> Press 'r' to reset"<<endl;
cout<<"------> Press 'Esc' to quit"<<endl<<endl;

src=imread("src.png",1);

namedWindow(winName,WINDOW_NORMAL);
setMouseCallback(winName,onMouse,NULL );
imshow(winName,src);

while(1){
char c=waitKey();
if(c=='s'&&ROI.data){
sprintf(imgName,"%d.jpg",i++);
imwrite(imgName,ROI);
cout<<" Saved "<<imgName<<endl;
}
if(c=='6') cropRect.x++;
if(c=='4') cropRect.x--;
if(c=='8') cropRect.y--;
if(c=='2') cropRect.y++;

if(c=='w') { cropRect.y--; cropRect.height++;}
if(c=='d') cropRect.width++;
if(c=='x') cropRect.height++;
if(c=='a') { cropRect.x--; cropRect.width++;}

if(c=='t') { cropRect.y++; cropRect.height--;}
if(c=='h') cropRect.width--;
if(c=='b') cropRect.height--;
if(c=='f') { cropRect.x++; cropRect.width--;}

if(c==27) break;
if(c=='r') {cropRect.x=0;cropRect.y=0;cropRect.width=0;cropRect.height=0;}
showImage();

}

return 0;
}

Sample Image



Related Topics



Leave a reply



Submit