Image 如何通过绘制边界框(或多边形)从图像中裁剪多个对象?
如何通过使用OpenCV使用鼠标绘制绑定框,从图像中裁剪多个对象。请参见下图: 我想用鼠标点击选择可乐罐的边界并裁剪它们 需要绘制多个多边形以选择对象的解决方案: 我能画单个多边形,但不能画多个多边形。代码如下: void鼠标句柄(int事件,int x,int y,int,void*) {Image 如何通过绘制边界框(或多边形)从图像中裁剪多个对象?,image,opencv,mouseevent,image-segmentation,Image,Opencv,Mouseevent,Image Segmentation,如何通过使用OpenCV使用鼠标绘制绑定框,从图像中裁剪多个对象。请参见下图: 我想用鼠标点击选择可乐罐的边界并裁剪它们 需要绘制多个多边形以选择对象的解决方案: 我能画单个多边形,但不能画多个多边形。代码如下: void鼠标句柄(int事件,int x,int y,int,void*) { }如果您只想绘制矩形,可以参考中的代码 如果你需要画多边形,请看下面的代码。可以使用鼠标左键单击来绘制多边形顶点。左双击将关闭多边形,然后开始新的多边形 请注意,添加删除顶点的选项可能会有所帮助,例如,
}如果您只想绘制矩形,可以参考中的代码
如果你需要画多边形,请看下面的代码。可以使用鼠标左键单击来绘制多边形顶点。左双击将关闭多边形,然后开始新的多边形 请注意,添加删除顶点的选项可能会有所帮助,例如,通过鼠标右键单击删除最接近的顶点 底部将向您展示如何保存裁剪的图像 代码:
#包括
#包括
使用名称空间std;
使用名称空间cv;
矢量多边形;
布尔·布德劳;
矢量多边形;
Mat3b img;
Mat3b层;
Mat3b工作;
void CallBackFunc(int事件、int x、int y、int标志、void*userdata)
{
if(event==event_LBUTTONDOWN)
{
//我的答案不可能重复有一个关于如何使用OpenCV在图像上绘制(和存储)多个矩形的工作示例。使用这些矩形,您可以使用Mat crop(image(rect))轻松裁剪原始图像
谢谢Miki!我想用多边形来实现它,因为对象的形状并不总是矩形的。我能画一个多边形,但不能画多个。你能建议如何画多个多边形吗?谢谢Miki!如果你能发布你的解决方案,那将是很大的帮助。非常感谢@Miki!
if (event == EVENT_LBUTTONDOWN && !drag)
{
if (flag1 == 0)
{
if (var == 0)
img1 = img0.clone();
point = Point(x, y);
circle(img1, point, 2, Scalar(0, 0, 255), -1, 8, 0);
pts[var] = point;
var++;
drag = 1;
if (var>1)
line(img1, pts[var - 2], point, Scalar(0, 0, 255), 2, 8, 0);
imshow("Source", img1);
}
}
if (event == EVENT_LBUTTONUP && drag)
{
imshow("Source", img1);
drag = 0;
}
if (event == EVENT_RBUTTONDOWN)
{
flag1 = 1;
img1 = img0.clone();
for (int i = var; i < numpts; i++)
pts[i] = point;
if (var != 0)
{
const Point* pts3[1] = { &pts[0] };
polylines(img1, pts3, &numpts, 1, 1, Scalar(0, 0, 0), 2, 8, 0);
}
for (int i = 0; i<var; i++)
{
minx = min(minx, pts[i].x);
maxx = max(maxx, pts[i].x);
miny = min(miny, pts[i].y);
maxy = max(maxy, pts[i].y);
}
lenx = maxx - minx;
leny = maxy - miny;
imshow("Source", img1);
}
if (event == EVENT_RBUTTONUP)
{
flag = var;
final = Mat::zeros(img0.size(), CV_8UC3);
res1 = Mat::zeros(img0.size(), CV_8UC1);
const Point* pts4[1] = { &pts[0] };
fillPoly(res1, pts4, &numpts, 1, Scalar(255, 255, 255), 8, 0);
bitwise_and(img0, img0, final, res1);
imshow("mask", res1);
imwrite("mask.png", res1);
imshow("Source", img1);
}
if (event == EVENT_MBUTTONDOWN)
{
for (int i = 0; i < numpts; i++)
{
pts[i].x = 0;
pts[i].y = 0;
}
var = 0;
flag1 = 0;
minx = INT_MAX; miny = INT_MAX; maxx = INT_MIN; maxy = INT_MIN;
imshow("Source", img0);
drag = 0;
}
Mat src = imread("abc.jpg");
minx = INT_MAX; miny = INT_MAX; maxx = INT_MIN; maxy = INT_MIN;
img0 = src;
channel = img0.channels();
res1 = Mat::zeros(img0.size(), CV_8UC1);
final = Mat::zeros(img0.size(), CV_8UC3);
//////////// source image ///////////////////
namedWindow("Source", 1);
setMouseCallback("Source", mouseHandler, NULL);
imshow("Source", img0);
imshow("mask", res1);
waitKey(0);
img0.release();
img1.release();
#include <opencv2\opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
vector<vector<Point>> polygons;
bool bDraw;
vector<Point> poly;
Mat3b img;
Mat3b layer;
Mat3b working;
void CallBackFunc(int event, int x, int y, int flags, void* userdata)
{
if (event == EVENT_LBUTTONDOWN)
{
//cout << "Left button of the mouse is clicked - position (" << x << ", " << y << ")" << endl;
// Refresh
working = layer.clone();
if (!bDraw)
{
// Init your polygon
poly.clear();
bDraw = true;
}
// Add Current Point
poly.push_back(Point(x, y));
// Draw Poly
for (size_t i = 1; i < poly.size(); ++i) {
line(working, poly[i - 1], poly[i], Scalar(0, 255, 0));
}
// Draw Points
for (size_t i = 0; i < poly.size(); ++i) {
circle(working, poly[i], 3, Scalar(0, 0, 255));
}
// Update
imshow("My Window", working);
}
else if (event == EVENT_MOUSEMOVE)
{
//cout << "Mouse move over the window - position (" << x << ", " << y << ")" << endl;
// If drawing, update rect width and height
if (!bDraw) return;
// Refresh
working = layer.clone();
// Draw Poly
for (size_t i = 1; i < poly.size(); ++i) {
line(working, poly[i - 1], poly[i], Scalar(0, 255, 0));
}
// Draw Points
for (size_t i = 0; i < poly.size(); ++i) {
circle(working, poly[i], 3, Scalar(0, 0, 255));
}
// Draw Current line
line(working, poly.back(), Point(x, y), Scalar(0, 255, 0));
// Update
imshow("My Window", working);
}
else if (event == EVENT_LBUTTONDBLCLK)
{
//cout << "Left button double clicked" << endl;
// Refresh
working = layer.clone();
// Add Current Point
poly.push_back(Point(x, y));
// Save poly, draw it on layer
polygons.push_back(poly);
// Draw Poly
for (size_t i = 1; i < poly.size(); ++i)
{
line(working, poly[i - 1], poly[i], Scalar(0, 255, 255));
}
// Draw closed poly
line(working, poly.back(), poly.front(), Scalar(0, 255, 255));
// Draw Points
for (size_t i = 0; i < poly.size(); ++i) {
circle(working, poly[i], 3, Scalar(0, 0, 255));
}
layer = working.clone();
bDraw = false;
// Update
imshow("My Window", working);
}
}
int main(int argc, char** argv)
{
bool bDraw = false;
// Read image from file
img = imread("path_to_image");
// initialize your temp images
layer = img.clone();
working = img.clone();
//if fail to read the image
if (img.empty())
{
cout << "Error loading the image" << endl;
return -1;
}
//Create a window
namedWindow("My Window", 1);
//set the callback function for any mouse event
setMouseCallback("My Window", CallBackFunc, NULL);
//show the image
imshow("My Window", working);
// Wait until user press 'q'
while ((waitKey(1) & 0xFF) != 'q');
// Create cropped images and show / save
for (size_t i = 0; i < polygons.size(); ++i)
{
Mat3b out(img.rows, img.cols, Vec3b(0, 0, 0));
Mat1b mask(img.rows, img.cols, uchar(0));
drawContours(mask, polygons, i, Scalar(255), CV_FILLED);
img.copyTo(out, mask);
Rect box = boundingRect(polygons[i]);
out = out(box).clone();
imshow("Crop #" + to_string(i), out);
waitKey(1);
//imwrite("Crop #" + to_string(i), out);
}
waitKey();
return 0;
}