Matlab 如何区分黑白棋盘格

Matlab 如何区分黑白棋盘格,matlab,image-processing,image-segmentation,Matlab,Image Processing,Image Segmentation,我想将棋盘图像的方块分类为黑色或白色方块的过程自动化。更进一步的步骤是区分它是一个空的正方形还是正方形中包含一块。到目前为止,我接近于使用正方形中心的平均强度将每个正方形分类为白色或黑色,但很难设置阈值。对于进一步的步骤(空方块或一块),我尝试了std2,但也有困难 这是我的原始图像,也是到目前为止我所接近的 以下是我的脚本: image = imerode(original,strel('disk',3)); image = imadjust(image,[],[],2); figure,i

我想将棋盘图像的方块分类为黑色或白色方块的过程自动化。更进一步的步骤是区分它是一个空的正方形还是正方形中包含一块。到目前为止,我接近于使用正方形中心的平均强度将每个正方形分类为白色或黑色,但很难设置阈值。对于进一步的步骤(空方块或一块),我尝试了
std2
,但也有困难

这是我的原始图像,也是到目前为止我所接近的

以下是我的脚本:

image = imerode(original,strel('disk',3));
image = imadjust(image,[],[],2);
figure,imshow(image),hold on;
for i = 1:length(cells)
  TL = cells(i).TL; %Cell's corner top left
  TR = cells(i).TR; %Cell's corner top right
  BL = cells(i).BL; %Cell's corner bottom left
  BR = cells(i).BR; %Cell's corner bottom right
  x = [TL(1) TR(1) BR(1) BL(1)];
  y = [TL(2) TR(2) BR(2) BL(2)];
  bw = poly2mask(x,y,size(image,1),size(image,2));
  measurements = regionprops(bw,'BoundingBox');
  cropped = imcrop(image, measurements.BoundingBox);
  m = regionprops(bw,'Centroid');
  x = m.Centroid(1);
  y = m.Centroid(2);
  w = 25; %width
  h = 25; %height
  tl = [round(x-w/2) round(y-h/2)];
  center = image(tl(1):tl(1)+w,tl(2):tl(2)+h,:);
  %stds(i) = std2(center);
  avgs(i) = mean2(center);
  if(avgs(i) > 55)
      str = "W";
  else
      str = "B";
  end
  text(x,y,str,'Color','red','FontSize',16);
end
编辑:下面的图像是编辑后的新结果

image = imerode(image,strel('disk',4));
image = image>160;

腐蚀后的二值化将帮助您找到空白的白色方块

通过这些,您可以更轻松地重建整个棋盘格,并估计占用的方块


您可以使用Matlabs内置棋盘方法
检测棋盘点数
棋盘
来查找棋盘的大小,并构建一个适当大小的新棋盘。由于只能存在两个可能的棋盘,请同时构造两个棋盘,并检查哪一个棋盘最匹配

img = imread('PNWSv.jpg'); %Load image

%Prepare image
I = rgb2gray(img);
I2 = imerode(I,strel('square',10));
bw = imbinarize(I2,'adaptive');

%Find checkerboard points
[imagePoints,boardSize] = detectCheckerboardPoints(bw);

%Find the size of the checkerboard fields
x = boardSize(2)-1;
y = boardSize(1)-1;
fields = cell(y,x);
for k = 1:length(imagePoints)
    [i,j] = ind2sub([y,x],k);
    fields{i,j} = imagePoints(k,:);
end
avgDx = mean(mean(diff(cellfun(@(x) x(1),fields),1,2)));
avgDy = mean(mean(diff(cellfun(@(x) x(2),fields),1,1)));

%Construct the two possibilities
ref1 = imresize(imbinarize(checkerboard),[avgDx,avgDy]*8);
ref2 = imcomplement(ref1);

%Check which ones fits the better
c1 = normxcorr2(ref1,I);
c2 = normxcorr2(ref2,I);

if max(c2(:))<max(c1(:))
    ref=ref1;
    c = c1;
else 
    ref=ref2;
    c = c2;
end

%Plot the checkerboard bounding box on top of the original image
[ypeak, xpeak] = find(c==max(c(:)));
yoffSet = ypeak-size(ref,1);
xoffSet = xpeak-size(ref,2);

imshow(img);
imrect(gca, [xoffSet+1, yoffSet+1, size(ref1,2), size(ref1,1)]); 
img=imread('PNWSv.jpg');%加载图像
%准备图像
I=RGB2灰色(img);
I2=iModel(I,strel('square',10));
bw=imbinarize(I2,“自适应”);
%查找棋盘点数
[imagePoints,boardSize]=检测电路板点(bw);
%查找棋盘格字段的大小
x=板尺寸(2)-1;
y=板尺寸(1)-1;
字段=单元(y,x);
对于k=1:长度(图像点)
[i,j]=ind2sub([y,x],k);
字段{i,j}=图像点(k,:);
结束
avgDx=平均值(平均值(差值(cellfun(@(x)x(1),字段),1,2));
avgDy=平均值(平均值(差值(cellfun(@(x)x(2),字段),1,1));
%构建两种可能性
参考1=imresize(imbinarize(棋盘格),[avgDx,avgDy]*8;
参考文献2=补码(参考文献1);
%检查哪一个更合适
c1=normxcorr2(参考文献1,I);
c2=normxcorr2(参考文献2,I);

如果max(c2(:)“你可以重建……并估算……”是一个很好的方向,但不是一个答案…@Adiel:谢谢你的建设性贡献。@YvesDaoust你用了什么strel来侵蚀?因为当我把棋盘左上角的方块二值化时,它们都变成了白色,失去了黑色,你不是在放大吗?你调整了阈值水平了吗?我已经编辑了这个问题,在经过二值化之后得到了新的结果。仍然在右边,我看到一些白色的方块标为黑色。所以我试着降低阈值,但是一些黑色方块在左上角被标记为白色谢谢你的回答,我会试试这个。然而,我得到了这个问题:警告:棋盘必须是不对称的:一边应该是偶数,另一边应该是奇数。否则,可能无法正确检测电路板的方向。未定义的函数或变量“ypeak2”。我已更新了答案以处理错误。关于警告,您可以忽略它。它仅用于测量字段的大小,从而测量电路板的大小。因此,它是否混淆了方向或找不到所有东西并不重要。查看此页面了解如何抑制警告(不要抑制所有)非常感谢,你做了我要求的额外工作!关于使用OpenCV的非matlab解决方案,参考refsee中给出了黑白方块的正确方案