北斗系统 VMware sorting path scrapy NEC vue全局组件 vue开发教程 vue配置 it教学视频 cmd查看mysql版本 spark数据清洗 python设置环境变量 java基础入门 java8时间 java系统时间 java连接sql linux用户 wps2011 雪地求生 东方头条邀请码 迅雷去广告版 系统工具箱 华为下拉开关设置 字典生成器 kz文件 调试js 微信预约系统 华为手环怎么连接手机 下拉框默认选中 巫师3福利 软件编程软件 dw网页设计教程 ps怎么做印章效果 cdr复制属性快捷键 微博实名认证 kindeditor漏洞 迅雷被封 myeclipse 苹果双开微信
当前位置: 首页 > 学习教程  > 编程语言

如何在图片中识别特定图像并找出(c语言和matlab)

2020/10/8 20:31:34 文章标签:

前言 导师给了一个任务,主要是在一张图片中识别出特定的图像,并标记出相应物体的位置(在坐标图上呈现),分别用c语言和matlab都实现一下来练手。 思路 参考了一些网上的代码,我这次实现的主要思路就是用鼠…

前言

导师给了一个任务,主要是在一张图片中识别出特定的图像,并标记出相应物体的位置(在坐标图上呈现),分别用c语言和matlab都实现一下来练手。

思路

参考了一些网上的代码,我这次实现的主要思路就是用鼠标获取目标图像中心点的像素值,并以这个点为中心扣出目标图像所在的图像块

首先遍历原图的每个像素点,与 中心点 的像素值比较,如果原图 p点 像素值的差值在允许的范围内,则开始遍历图像块的第一个像素点(左上的点)以及以p点为中心的同样大小的图像块的第一个像素点(左上的点),如果图像块遍历完,每个像素点的差值都在允许范围内,则保存p点;如果任有一个像素点的差值过大,则遍历p点下一个点,继续与中心点比较像素值。

c语言代码


#include<opencv2/opencv.hpp>
#include <opencv2/highgui/highgui_c.h>
#include<iostream>
using namespace cv;
using namespace std;

Mat src;//原图,用来标点
Mat dst;//最后画圈所用的图
Mat ssrc;//中间呈现的图像块

int w = 13;
static Point pre_pt ;
static Point p;
vector<Point2f> vp;

int getSrcPixel(int x, int y)//遍历原图中的坐标点
{
	//int G = (int)im.at<Vec3b>(3, 5)[2];//读取各点RGB的值
	int sum = 0;
	sum = (int)src.at<Vec3b>(x, y)[0] + (int)src.at<Vec3b>(x, y)[1] + (int)src.at<Vec3b>(x, y)[2];
	return sum;
}

int getSsrcPixel(int x, int y)//遍历图像块的坐标点
{
	int sum = 0;
	sum = (int)ssrc.at<Vec3b>(x, y)[0] + (int)ssrc.at<Vec3b>(x, y)[1] + (int)ssrc.at<Vec3b>(x, y)[2];
	return sum;
}

void judge()
{
	int i = 0;
	while (i<vp.size()-1)
	{
		if (vp[i].x == vp[i + 1].x)
			if (vp[i].y + 1 == vp[i + 1].y || vp[i].y - 1 == vp[i + 1].y) {
				vp.erase(vp.begin() + i);
				continue;
			}
		if (vp[i].y == vp[i + 1].y)
			if (vp[i].x + 1 == vp[i + 1].x || vp[i].x - 1 == vp[i + 1].x) {
				vp.erase(vp.begin() + i);
				continue;
			}
		i++;
				
	}
}


void findPoint()
{
	int width = src.rows;//水平
	int lonth = src.cols;//垂直
	int err = 0;
	int q, p;
	for (int i = w; i <= width - w; i++) {
		for (int j = w; j <= lonth - w; j++) {
			int flag = 0;
			err =abs( getSrcPixel(i, j) - getSsrcPixel(w, w));
			if( err > 230)
				continue;
			else
				for (int k = i - w; k < i + w; k++) {
					for (int t = j - w; t < j + w; t++) {
						q = k - (i - w);
						p = t - (j - w);
						err = abs(getSrcPixel(k, t) - getSsrcPixel(q, p));
						if (err > 230) {
							flag = 1;
							break;
						}
					}
					if (flag==1)
					{
						break;
					}
				}
			if (flag == 0) {
				//进点集
				vp.push_back(Point(j, i));
			}
		}
	}
}

void on_mouse(int event, int x, int y, int flags, void* ustc)
{
	int lonth = src.cols;
	//char temp_1[20];
	switch (event)
	{
	case EVENT_LBUTTONDOWN: {
		pre_pt = Point(x, y);
	} break;
	case EVENT_LBUTTONUP: {
		printf("%d %d ", pre_pt.x, pre_pt.y);
		destroyWindow("src");
		Rect rect(pre_pt.x - w, pre_pt.y - w, 2 * w, 2 * w);
		ssrc = src(rect);
		imshow("图像块", ssrc);
		findPoint();
		judge();
		printf("共有%d个 ", int(vp.size()));
		for (int i = 0; i < vp.size(); i++) {
			printf("\n %f  %f ", vp[i].x, vp[i].y);
			circle(dst, vp[i],13, CV_RGB(255, 0, 0), 1, 5, 0);
			char temp[20];
			sprintf_s(temp, "(%d,%d)", int(vp[i].x), lonth-int(vp[i].y));
			putText(dst, temp, Point(vp[i].x-2.5*w, vp[i].y+2*w), CV_FONT_HERSHEY_SCRIPT_SIMPLEX, 0.5, Scalar(255, 0, 0));
		}
		imshow("dst", dst);
		

	}break;
	}

}

int main()
{
	namedWindow("src", WINDOW_AUTOSIZE);//WINDOW_AUTOSIZE:系统默认,显示自适应
	src = imread("C:/Users/wwwww/Desktop/图像识别/123.png",1);
	//1:为原图颜色,0:为灰度图,黑白颜色
	src.copyTo(dst);
	setMouseCallback("src", on_mouse, 0);
	imshow("src", src);
	waitKey(0);
	return 0;

}

matlab代码

close all; 
clear all; 
clc; 

im = imread('C:\Users\wwwww\Desktop\图像识别\123.png');
im=imresize(im,1);
figure; imshow(im); 

[m,n,c]=size(im);
im = im2double(im); 

%点击选取一个图像块
[c, r] = ginput(1);
c = floor(c); 
r = floor(r); 

%图像块宽度
w = 8;
block_im = im(r-w:r+w, c-w:c+w, :); 
  
err = 0; 

%可能匹配的位置
pnts = []; 

%匹配的图像块太多
too_many_match = 0; 

for i =w:m-w
    for j =w:n-w
        f=0;
        err = sum(abs(im(i,j,:)-block_im(w, w,:)));  %所选点的三个通道的取值的差       
        if  err > 0.9
            continue;   
        end
        
        for k=i-w+1:i+w
            for t=j-w+1:j+w
                q=k-(i-w);
                p=t-(j-w);
                err=sum(abs(im(k,t,:)-block_im(q,p,:)));
                if err> 0.9
                    f=1;
                    break;
                end
            end
            if f==1
                break; 
            end
        end
        if f~=1
            pnts = [pnts; [i,j]]; 
        end
        %如果匹配的点太多,那么就要重新选择图像块
        if size(pnts,1) > 50
            too_many_match  = 1; 
            break;
        end 

    
    end
    if 1 == too_many_match
        break;
    end
end 

%pnts 
[m,n,c]=size(im);
hold on; 
len = size(pnts,1);

%删除相邻的重复点
i=1;
while(i<len)
    if pnts(i,1)==pnts(i+1,1)||pnts(i,1)+1==pnts(i+1,1)||pnts(i,1)-1==pnts(i+1,1)
        if pnts(i,2)+1==pnts(i+1,2)||pnts(i,2)-1==pnts(i+1,2)
            pnts([i],:)=[];
        end
        if i==size(pnts,1)
            len=size(pnts,1)
            break
        end
    end
    if pnts(i,2)==pnts(i+1,2)||pnts(i,2)+1==pnts(i+1,2)||pnts(i,2)-1==pnts(i+1,2)
        if pnts(i,1)+1==pnts(i+1,1)||pnts(i,1)-1==pnts(i+1,1)
            pnts([i],:)=[];
        end
    end
    i=i+1;
    len=size(pnts,1);
end  



for i=1:len
    plot(pnts(i,2), pnts(i,1), 'ro');     
end 
block_im=imresize(block_im,2);
figure;
imshow(block_im);  title('图像块');
figure;
plot(pnts(:,2),pnts(:,1),'.');

set(gca,'xaxislocation','top','yaxislocation','left','ydir','reverse');
len


运行结果

原图在这里插入图片描述
在这里插入图片描述

最后

因为我所用的方法只是粗略比较像素值,所以误差会非常大,只是能大致识别出来这些图像,而且把允许范围的阈值设置的比较高,所以还是可以再优化的。


本文链接: http://www.dtmao.cc/news_show_250338.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?