... другое старомодное решение - чисто , основанное на обработке HSV :
Слово об эвристике при обработке ВПГ:
Вот код MATLAB, который нужно сделать (предупреждение: код далеко не оптимизирован !!! Я использовал методы, не рекомендуемые для программирования на MATLAB, просто чтобы иметь возможность отслеживать что-либо в процессе - это может быть значительно оптимизировано) :
% clear everything
clear;
pack;
close all;
close all hidden;
drawnow;
clc;
% initialization
ims=dir('./*.jpg');
num=length(ims);
imgs={};
hsvs={};
masks={};
dilated_images={};
measurements={};
boxs={};
for i=1:num,
% load original image
imgs{end+1} = imread(ims(i).name);
flt_x_size = round(size(imgs{i},2)*0.005);
flt_y_size = round(size(imgs{i},1)*0.005);
flt = fspecial( 'average', max( flt_y_size, flt_x_size));
imgs{i} = imfilter( imgs{i}, flt, 'same');
% convert to HSV colorspace
hsvs{end+1} = rgb2hsv(imgs{i});
% apply a hard thresholding and binary operation to construct the mask
masks{end+1} = medfilt2( ~(hsvs{i}(:,:,1)>(210/360) & hsvs{i}(:,:,1)<(320/360))&hsvs{i}(:,:,3)>0.4);
% apply morphological dilation to connect distonnected components
strel_size = round(0.03*max(size(imgs{i}))); % structuring element for morphological dilation
dilated_images{end+1} = imdilate( masks{i}, strel('disk',strel_size));
% do some measurements to eliminate small objects
measurements{i} = regionprops( dilated_images{i},'Perimeter','Area','BoundingBox');
for m=1:length(measurements{i})
if (measurements{i}(m).Area < 0.02*numel( dilated_images{i})) || (measurements{i}(m).BoundingBox(3)>1.2*measurements{i}(m).BoundingBox(4))
dilated_images{i}( round(measurements{i}(m).BoundingBox(2):measurements{i}(m).BoundingBox(4)+measurements{i}(m).BoundingBox(2)),...
round(measurements{i}(m).BoundingBox(1):measurements{i}(m).BoundingBox(3)+measurements{i}(m).BoundingBox(1))) = 0;
end
end
dilated_images{i} = dilated_images{i}(1:size(imgs{i},1),1:size(imgs{i},2));
% compute the bounding box
[y,x] = find( dilated_images{i});
if isempty( y)
boxs{end+1}=[];
else
boxs{end+1} = [ min(x) min(y) max(x)-min(x)+1 max(y)-min(y)+1];
end
end
%%% additional code to display things
for i=1:num,
figure;
subplot(121);
colormap gray;
imshow( imgs{i});
if ~isempty(boxs{i})
hold on;
rr = rectangle( 'position', boxs{i});
set( rr, 'EdgeColor', 'r');
hold off;
end
subplot(122);
imshow( imgs{i}.*uint8(repmat(dilated_images{i},[1 1 3])));
end
В результатах я показываю замаскированное изображение и ограничивающий прямоугольник.
В статье Википедии о ложных пробуждениях есть следующий лакомый кусочек:
Функция
pthread_cond_wait ()
в Linux реализована с использованиемфутекса.
системный вызов. Каждый системный вызов блокировки в Linux резко возвращается сEINTR
, когда процесс получает сигнал. ...pthread_cond_wait ()
не может перезапустить ожидание, потому что он может пропустить настоящее пробуждение за то короткое время, когда оно было вне системного вызоваfutex
. Этого состояния гонки можно избежать, только проверив инвариант вызывающей стороной. Таким образом, сигнал POSIX будет генерировать ложное пробуждение.
Резюме : Если процесс Linux получает сигнал, его ожидающие потоки будут наслаждаться приятным, горячим ложным пробуждением .
Я покупаю его. Который'
Кэмерон Парди недавно написал сообщение в блоге о том, что у него возникла проблема ложного пробуждения. Так что да, такое бывает
. Я предполагаю, что это указано в спецификации (как возможность) из-за ограничений некоторых платформ, на которых развертывается Java? хотя могу ошибаться!