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

前言

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

思路

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

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

c语言代码


#include
#include 
#include
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(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;elsefor (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-wfor j =w:n-wf=0;err = sum(abs(im(i,j,:)-block_im(w, w,:)));  %所选点的三个通道的取值的差       if  err > 0.9continue;   endfor k=i-w+1:i+wfor t=j-w+1:j+wq=k-(i-w);p=t-(j-w);err=sum(abs(im(k,t,:)-block_im(q,p,:)));if err> 0.9f=1;break;endendif f==1break; endendif f~=1pnts = [pnts; [i,j]]; end%如果匹配的点太多,那么就要重新选择图像块if size(pnts,1) > 50too_many_match  = 1; break;end endif 1 == too_many_matchbreak;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],:)=[];endif i==size(pnts,1)len=size(pnts,1)breakendendif 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],:)=[];endendi=i+1;len=size(pnts,1);
end  for i=1:lenplot(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

运行结果

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

最后

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


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部