using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
namespace ConsoleApp
{
internal class Program
{
static void Main(string[] args)
{
Mat org = Cv2.ImRead("image/cards.png");
Mat imgray = new Mat();
Cv2.CvtColor(org, imgray, ColorConversionCodes.BGR2GRAY);
Cv2.ImShow("imgray", imgray);
// 白色背景
Mat threshold = new Mat();
Cv2.Threshold(imgray, threshold, 244, 255, ThresholdTypes.BinaryInv); // 把黑白颜色反转
Cv2.ImShow("after threshold", threshold);
Point[][] contours = new Point[][] { };
HierarchyIndex[] hierarcy;
Cv2.FindContours(threshold, out contours, out hierarcy, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple, null);
List<(int, double)> areas = new List<(int, double)>();
for (int i = 0; i < contours.Length; i++)
{
areas.Add((i, Cv2.ContourArea(contours[i]))); // 面积大小
}
// 按面积大小,从大到小排序
var a2 = areas.OrderByDescending(x => x.Item2).ToList();
foreach (var area in a2)
{
if (area.Item2 < 150)
continue;
Mat img22 = new Mat();
org.CopyTo(img22); //逐个contour 显示
Cv2.DrawContours(img22, contours, area.Item1, new Scalar(0, 0, 255), 3);
Console.WriteLine(area);
Cv2.ImShow("drawContours", img22);
img22.Dispose(); // C# 中这里一定要释放内存,Mat库默认不会释放
if (Cv2.WaitKey(200) == 'q')
break;
}
// 获取最大或某个contour,剪切
int idx = a2[1].Item1;
// Create mask where white is what we want, black otherwise
Mat mask = new Mat(org.Size(), org.Type(), new Scalar(0, 0, 0));
// Draw filled contour in mask
Cv2.DrawContours(mask, contours, idx, new Scalar(0, 255, 0), -1);
// Extract out the object and place into output image
Mat matout = new Mat(org.Size(), org.Type(), new Scalar(0, 0, 0));
org.CopyTo(matout, mask);
Cv2.ImShow("out_contour.jpg", matout);
//roi方法
idx = a2[4].Item1;
Rect rect = Cv2.BoundingRect(contours[idx]);
Mat matroi = new Mat(org, rect);
Cv2.ImShow("out_contour-roi4.jpg", matroi);
Cv2.WaitKey(0);
}
}
}
C++版本运行代码如下:
#include <opencv2/opencv.hpp>
#include <opencv2/cvconfig.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <string>
#include <cmath>
#include <iostream>
using namespace cv;
using namespace std;
struct areaPack
{
int i;
double area;
};
int main()
{
Mat org = cv::imread("../images/cards.png");
Mat imgray;
cv::cvtColor(org, imgray, COLOR_BGR2GRAY);
cv::imshow("imgray", imgray);
// 白色背景
Mat threshold;
cv::threshold(imgray, threshold, 244, 255, THRESH_BINARY_INV); // 把黑白颜色反转
cv::imshow("after threshold", threshold);
vector<vector<Point>> contours;
vector<Vec4i> hierarcy;
findContours(threshold, contours, hierarcy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
vector<areaPack> areas;
for (int i = 0; i < contours.size(); i++)
{
areaPack p;
p.i = i;
p.area = cv::contourArea(contours[i]); // 面积大小
areas.push_back(p);
}
// 按面积大小,从大到小排序
sort(areas.begin(), areas.end(), [](const areaPack& a, const areaPack& b) {
return a.area > b.area;
});
vector<areaPack> a2 = areas;
for (int i = 0; i < a2.size(); i++)
{
if (a2[i].area < 150)
continue;
Mat img22;
org.copyTo(img22); //逐个contour 显示
cv::drawContours(img22, contours, a2[i].i, Scalar(0, 0, 255), 3);
cv::imshow("drawContours", img22);
if (cv::waitKey(200) == 'q')
break;
}
// 获取最大或某个contour,剪切
int idx = a2[1].i;
// Create mask where white is what we want, black otherwise
Mat mask(org.size(), org.type(), Scalar(0, 0, 0));
// Draw filled contour in mask
cv::drawContours(mask, contours, idx, Scalar(0, 255, 0), -1);
// Extract out the object and place into output image
Mat matout(org.size(), org.type(), Scalar(0, 0, 0));
org.copyTo(matout, mask);
cv::imshow("out_contour.jpg", matout);
//roi方法
idx = a2[4].i;
Rect rect = cv::boundingRect(contours[idx]);
Mat matroi = org(rect);
cv::imshow("out_contour-roi4.jpg", matroi);
cv::waitKey(0);
}
Python版本运行代码如下:
import cv2
import numpy as np
org = cv2.imread('../images/cards.png')
imgray = cv2.cvtColor(org, cv2.COLOR_BGR2GRAY)
cv2.imshow('imgray', imgray)
# 白色背景
ret, threshold = cv2.threshold(imgray, 244, 255, cv2.THRESH_BINARY_INV) # 把黑白颜色反转
cv2.imshow('after threshold', threshold)
contours, hierarchy = cv2.findContours(threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
areas = list()
for i, cnt in enumerate(contours):
areas.append((i, cv2.contourArea(cnt)))#面积大小
#按面积大小,从大到小排序
a2 = sorted(areas, key=lambda d: d[1], reverse=True)
cv2.waitKey(10)#要先按一下键盘
for i, are in a2:
if are < 150:
continue
img22 = org.copy()#逐个contour 显示
cv2.drawContours(img22, contours, i, (0, 0, 255), 3)
print(i, are)
cv2.imshow('drawContours', img22)
k = cv2.waitKey(200)
if k == ord('q'):
break
# 获取最大或某个contour,剪切
idx = a2[1][0]
mask = np.zeros_like(org) # Create mask where white is what we want, black otherwise
cv2.drawContours(mask, contours, idx, (0, 255, 0), -1) # Draw filled contour in mask
out = np.zeros_like(org) # Extract out the object and place into output image
out[mask == 255] = org[mask == 255]
cv2.imshow('out_contour.jpg', out)
# roi方法
idx = a2[4][0]
x, y, w, h = cv2.boundingRect(contours[idx])
roi = org[y:y + h, x:x + w]
cv2.imshow('out_contour-roi4.jpg', roi)
cv2.waitKey(0)
cv2.destroyAllWindows()
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
namespace ConsoleApp
{
internal class Program
{
static void Main(string[] args)
{
Mat org = Cv2.ImRead("image/cards.png");
Mat imgray = new Mat();
Cv2.CvtColor(org, imgray, ColorConversionCodes.BGR2GRAY);
Cv2.ImShow("imgray", imgray);
// 白色背景
Mat threshold = new Mat();
Cv2.Threshold(imgray, threshold, 244, 255, ThresholdTypes.BinaryInv); // 把黑白颜色反转
Cv2.ImShow("after threshold", threshold);
Point[][] contours = new Point[][] { };
HierarchyIndex[] hierarcy;
Cv2.FindContours(threshold, out contours, out hierarcy, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple, null);
List<(int, double)> areas = new List<(int, double)>();
for (int i = 0; i < contours.Length; i++)
{
areas.Add((i, Cv2.ContourArea(contours[i]))); // 面积大小
}
// 按面积大小,从大到小排序
var a2 = areas.OrderByDescending(x => x.Item2).ToList();
foreach (var area in a2)
{
if (area.Item2 < 150)
continue;
Mat img22 = new Mat();
org.CopyTo(img22); //逐个contour 显示
Cv2.DrawContours(img22, contours, area.Item1, new Scalar(0, 0, 255), 3);
Console.WriteLine(area);
Cv2.ImShow("drawContours", img22);
img22.Dispose(); // C# 中这里一定要释放内存,Mat库默认不会释放
if (Cv2.WaitKey(200) == 'q')
break;
}
// 获取最大或某个contour,剪切
int idx = a2[1].Item1;
// Create mask where white is what we want, black otherwise
Mat mask = new Mat(org.Size(), org.Type(), new Scalar(0, 0, 0));
// Draw filled contour in mask
Cv2.DrawContours(mask, contours, idx, new Scalar(0, 255, 0), -1);
// Extract out the object and place into output image
Mat matout = new Mat(org.Size(), org.Type(), new Scalar(0, 0, 0));
org.CopyTo(matout, mask);
Cv2.ImShow("out_contour.jpg", matout);
//roi方法
idx = a2[4].Item1;
Rect rect = Cv2.BoundingRect(contours[idx]);
Mat matroi = new Mat(org, rect);
Cv2.ImShow("out_contour-roi4.jpg", matroi);
Cv2.WaitKey(0);
}
}
}
C++版本运行代码如下:
#include <opencv2/opencv.hpp>
#include <opencv2/cvconfig.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <string>
#include <cmath>
#include <iostream>
using namespace cv;
using namespace std;
struct areaPack
{
int i;
double area;
};
int main()
{
Mat org = cv::imread("../images/cards.png");
Mat imgray;
cv::cvtColor(org, imgray, COLOR_BGR2GRAY);
cv::imshow("imgray", imgray);
// 白色背景
Mat threshold;
cv::threshold(imgray, threshold, 244, 255, THRESH_BINARY_INV); // 把黑白颜色反转
cv::imshow("after threshold", threshold);
vector<vector<Point>> contours;
vector<Vec4i> hierarcy;
findContours(threshold, contours, hierarcy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
vector<areaPack> areas;
for (int i = 0; i < contours.size(); i++)
{
areaPack p;
p.i = i;
p.area = cv::contourArea(contours[i]); // 面积大小
areas.push_back(p);
}
// 按面积大小,从大到小排序
sort(areas.begin(), areas.end(), [](const areaPack& a, const areaPack& b) {
return a.area > b.area;
});
vector<areaPack> a2 = areas;
for (int i = 0; i < a2.size(); i++)
{
if (a2[i].area < 150)
continue;
Mat img22;
org.copyTo(img22); //逐个contour 显示
cv::drawContours(img22, contours, a2[i].i, Scalar(0, 0, 255), 3);
cv::imshow("drawContours", img22);
if (cv::waitKey(200) == 'q')
break;
}
// 获取最大或某个contour,剪切
int idx = a2[1].i;
// Create mask where white is what we want, black otherwise
Mat mask(org.size(), org.type(), Scalar(0, 0, 0));
// Draw filled contour in mask
cv::drawContours(mask, contours, idx, Scalar(0, 255, 0), -1);
// Extract out the object and place into output image
Mat matout(org.size(), org.type(), Scalar(0, 0, 0));
org.copyTo(matout, mask);
cv::imshow("out_contour.jpg", matout);
//roi方法
idx = a2[4].i;
Rect rect = cv::boundingRect(contours[idx]);
Mat matroi = org(rect);
cv::imshow("out_contour-roi4.jpg", matroi);
cv::waitKey(0);
}
Python版本运行代码如下:
import cv2
import numpy as np
org = cv2.imread('../images/cards.png')
imgray = cv2.cvtColor(org, cv2.COLOR_BGR2GRAY)
cv2.imshow('imgray', imgray)
# 白色背景
ret, threshold = cv2.threshold(imgray, 244, 255, cv2.THRESH_BINARY_INV) # 把黑白颜色反转
cv2.imshow('after threshold', threshold)
contours, hierarchy = cv2.findContours(threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
areas = list()
for i, cnt in enumerate(contours):
areas.append((i, cv2.contourArea(cnt)))#面积大小
#按面积大小,从大到小排序
a2 = sorted(areas, key=lambda d: d[1], reverse=True)
cv2.waitKey(10)#要先按一下键盘
for i, are in a2:
if are < 150:
continue
img22 = org.copy()#逐个contour 显示
cv2.drawContours(img22, contours, i, (0, 0, 255), 3)
print(i, are)
cv2.imshow('drawContours', img22)
k = cv2.waitKey(200)
if k == ord('q'):
break
# 获取最大或某个contour,剪切
idx = a2[1][0]
mask = np.zeros_like(org) # Create mask where white is what we want, black otherwise
cv2.drawContours(mask, contours, idx, (0, 255, 0), -1) # Draw filled contour in mask
out = np.zeros_like(org) # Extract out the object and place into output image
out[mask == 255] = org[mask == 255]
cv2.imshow('out_contour.jpg', out)
# roi方法
idx = a2[4][0]
x, y, w, h = cv2.boundingRect(contours[idx])
roi = org[y:y + h, x:x + w]
cv2.imshow('out_contour-roi4.jpg', roi)
cv2.waitKey(0)
cv2.destroyAllWindows()