根据图像中局部颜色特征,获取该位置
一、根据特定颜色切割,输出二值化图像
public static void inRange(Mat src,
Scalar lowerb,
Scalar upperb,
Mat dst)
例如 new Scalar(28,10,255);
public Scalar(double v0, double v1, double v2) {
this.val = new double[]{v0, v1, v2, 0.0D};
}
相当于颜色数组,mac可以通过数码测试计来获取
计算规则为:
- For every element of a single-channel input array: 单通道计算规则
dst(I)= lowerb(I)_0 <= src(I)_0 <= upperb(I)_0
- For two-channel arrays: 二通道
dst(I)= lowerb(I)_0 <= src(I)_0 <= upperb(I)_0 land lowerb(I)_1 <= src(I)_1 <= upperb(I)_1
三通道处理方式一样,每个通道都大于等于lowerb小于upperb
输出二值化图像,在范围内,标记255及白色不在该范围内标记0黑色
二、获取该图像轮廓:
public static void findContours(Mat image,
java.util.List<MatOfPoint> contours,
Mat hierarchy,
int mode,
int method)
获取图像轮廓 List<MatOfPoint> ,满足该函数策略的轮廓集合
Imgproc.RETR_EXTERNAL 只检测最外围轮廓;Imgproc.RETR_CCOMP:能获取外层和内层轮廓
Imgproc.CHAIN_APPROX_SIMPLE:仅保存轮廓的拐点信息,例如矩形只需要四个点来保存
目前还没怎么用到其他参数,具体还需要通过实际尝试,得出结论
三、根据轮廓,画出矩阵,查看符合条件的图形
public static void rectangle(Mat img,
Point pt1,
Point pt2,
Scalar color,
int thickness,
int lineType,
int shift)
通过函数 public static Rect boundingRect(MatOfPoint points):计算并返回指定点集的最小右上边界矩形,水平垂直的矩阵
获取该矩阵:
int x = rect.x;
int y = rect.y;
int w = rect.width;
int h = rect.height;
再rectangle画出矩形查看,我们根据获取的坐标点的四个坐标,其实就可以大概定位到所需要的位置
四、Demo代码如下:
Mat img = Imgcodecs.imread(originalImgPath);
//克隆图像mat
Mat dstImage = img.clone();
Imgproc.medianBlur(img, dstImage, 7);
//输出图片查看
Imgcodecs.imwrite("/Users/wuxi/Desktop/medianBlur.jpg",dstImage);
Mat mask = new Mat();
Core.inRange(dstImage, new Scalar(0,0,240), new Scalar(30,30,255), mask);
//输出图片查看,二值化图片
Imgcodecs.imwrite("/Users/wuxi/Desktop/erzhihua.jpg",mask);
List<MatOfPoint> contours = new ArrayList<>();
Imgproc.findContours(mask,contours,new Mat(),Imgproc.RETR_EXTERNAL,Imgproc.CHAIN_APPROX_SIMPLE);
JSONObject jsonObject = new JSONObject();
List<Map> list=new ArrayList<>();
System.out.println("contours"+contours.size());
for (MatOfPoint cnt : contours) {
Rect rect = Imgproc.boundingRect(cnt);
int x = rect.x;
int y = rect.y;
int w = rect.width;
int h = rect.height;
// 如果存在多个轮廓,需要自己通过该矩阵特征过滤不需要的轮廓
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("x",x);
map.put("y",y);
Imgproc.rectangle(img, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),new Scalar(0, 0,255), 2); //线的宽度
//输出图片查看
Imgcodecs.imwrite("/Users/wuxi/Desktop/juxing2.jpg",img);
原始图像:
矩阵图像
参考:
https://blog.csdn.net/eric_e/article/details/79591025
https://blog.csdn.net/qq_19707521/article/details/78367684