考虑到你控制成像条件,我建议你稍微改进一下。
首先,让您的相机直接指向药盒所在的表面。这将使碉堡的几何形状更加简单。
还要尽量避免阴影。他们不是不可能处理的,但没有问题会更容易。良好的照明可以轻松解决大多数计算机视觉问题。
您有一个白色背景上的红色框。分割出盒子应该很容易(只需检测红色像素)。找到最大的连通分量,然后确定四个角。这给了你一个矩形。既然你知道盒子的几何形状,你现在需要做的就是把矩形分成一个 7x2 的网格。这消除了检测单个细胞的需要。
如果您真的想检测单个单元格,请考虑将单元格的边缘涂成黑色。再次,面对困难的视力问题,调整你的世界,直到问题变得容易。 :)
编辑
最好使用蓝色胶带。蓝色在照片中很好地呈现出来。 JPEG压缩确实使区分颜色变得比必要的困难,我希望您可以在不通过JPEG的情况下读取和处理图像。这是我得到的:
有一点我没有在意的透视失真。应该也可以对此进行校正,因为找到框的轮廓很简单,并且可以告诉您有关失真的所有信息。
我使用过 MATLAB,因为这是我最熟悉的快速原型制作方法。我希望你在将它翻译成 Python 时不会遇到麻烦。我使用了 DIPimage 工具箱,它有一个 Python 对应物 PyDIP(我使用的所有功能都可以从 Python 中获得)。 Here is the GitHub repository.
% Read in image
img = imread('https://i.stack.imgur.com/AXkGH.jpg');
img = joinchannels('rgb',img);
% Convert to Lab color space
lab = colorspace(img,'lab');
% Get red area, make it into a single large blob, and measure its orientation
red = lab{2} > 30;
red = closing(red,20);
msr = measure(red,[],'feret');
[~,indx] = max(msr);
angle = msr(indx(1)).feret(5);
% Rotate the original image to make the box horizontal
img = colorspace(rotation(img,-angle-pi/2,'linear','add max'),'rgb'); % BUG! rotation loses color space
% Convert to Lab color space again
lab = colorspace(img,'lab');
% Get blue masking tape
blue = lab{3} < -10;
% Poor man's Radon transform -- horizontal lines
horiz = sum(blue,[],1);
% Expect three peaks
horiz = gaussf(horiz,3);
peaks = find(maxima(horiz));
horiz = double(horiz(peaks));
[~,indx] = sort(horiz,'descend');
horiz = sort(peaks(indx(1:3))); % 3 largest maxima
% Poor man's Radon transform -- vertical lines
vert = sum(blue,[],2);
% Expect eight peaks
vert = gaussf(vert,3);
peaks = find(maxima(vert));
vert = double(vert(peaks));
[~,indx] = sort(vert,'descend');
vert = sort(peaks(indx(1:8))); % 8 largest maxima
% Draw lines over rotated input image
for ii=1:8
img(vert(ii),horiz(1):horiz(end)) = [0,255,0];
end
for ii=1:3
img(vert(1):vert(end),horiz(ii)) = [0,255,0];
end