Difference (mistake) between two images

조회 수: 3 (최근 30일)
Audrius Bieliunas
Audrius Bieliunas 2022년 11월 13일
댓글: Audrius Bieliunas 2022년 12월 23일
Hello, I need help with a Master project. I need rectangle human mistake, in connector seals.
In picture 1.jpg, I have a connector with 17 white seals, this is model1.
In picture 2.jpg, I have a connector with 16 white seals, this is model2. (MODEL WITH MISTAKE, 1 missing white seal)
In autocad drawing i want to color or choose what model will be, somehow automatic combine (register) it with the model2 or new image with mistake, and rectangle that place, like in the last image. All images will be created from same height and angle.
so long i can to bwlabel the drawing(image) and choose what circles i want to paint.
rectangled mistake.
I cant use imregcorr to register autocad drawing with model1 because, its working just on rgb image, and i cant bwlabel the autocaddrawing without imbinarizing it. So thx for your time and waiting for answer.

채택된 답변

DGM
DGM 2022년 11월 14일
This isn't exactly production ready, but it's a rough example. This uses CVT tools to do the registration estimation. I don't know how robust this will be with the given settings in the registration function. I don't have CVT and I don't have but the one image to try it on.
% get the images, discard color
good = imread('good.jpg');
bad = imread('mistake.jpg');
good = rgb2gray(good);
bad = rgb2gray(bad);
% detect the plugs
goodplug = imfill(imbinarize(good),'holes');
badplug = imfill(imbinarize(bad),'holes');
goodplug = bwareaopen(goodplug,100);
badplug = bwareaopen(badplug,100);
% remove the plugs from both images
goodnoplug = good;
goodnoplug(goodplug) = 0;
badnoplug = bad;
badnoplug(badplug) = 0;
montage({goodnoplug badnoplug})
% attempt to register the images (requires CVT)
movreg = registerImages_connector(badnoplug,goodnoplug);
% use the image registration to register the plug masks
badplugadj = imwarp(badplug,movreg.InitialRefObj,movreg.Transformation, ...
'OutputView',movreg.ResultRefObj,'SmoothEdges', true);
montage({goodplug badplugadj})
% split the blobs in the good plug mask
goodplug = bwdist(~goodplug)>=5; % adjust radius if necessary
imshow(goodplug)
% find blob centroids as linear indices
S = regionprops(goodplug,'centroid');
plugidx = round(vertcat(S.Centroid));
plugidx = sub2ind(size(goodplug),plugidx(:,2),plugidx(:,1));
% check those locations in the registered image under test
plugismissing = ~badplugadj(plugidx)
plugismissing = 17×1 logical array
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
  댓글 수: 20
DGM
DGM 2022년 12월 20일
See if this is what you're looking for. The low contrast with the gray plugs is a bit of an obstacle, so I chose to change the way they're being detected in the last part. The first half is basically unchanged except for the different input files and plug list.
% %%%% PROCESS REFERENCE IMAGE %%%%
% get the image, discard color
reference = imread('goodedgecase.jpg');
reference = rgb2gray(reference);
% detect the plugs
refplug = imfill(imbinarize(reference),'holes');
refplug = bwareaopen(refplug,100);
% remove the plugs from image
refnoplug = reference;
refnoplug(refplug) = 0;
% detect holes
holeth = 20;
maxspecklearea = 100;
solidityrange = [0.7 1];
eccentrange = [0 0.95];
refholes = refnoplug <= holeth;
refholes = ~bwareaopen(~refholes,maxspecklearea);
refholes = bwareaopen(refholes,maxspecklearea);
refholes = bwpropfilt(refholes,'solidity',solidityrange);
refholes = bwpropfilt(refholes,'eccentricity',eccentrange);
% calculate convex hull and object rotation
refhull = bwconvhull(refholes);
S = regionprops(refhull,'minferetproperties');
thref = S(1).MinFeretAngle - 90;
% correct images for rotation
refhull = imrotate(refhull,thref);
refplug = imrotate(refplug,thref);
% close-crop plug mask based on extent of convhull
S = regionprops(refhull,'boundingbox');
rect = round(S.BoundingBox);
xrange = rect(1):sum(rect([1 3]));
yrange = rect(2):sum(rect([2 4]));
refplug = refplug(yrange,xrange);
% stuff needed to create the template
%refholes = imrotate(refholes,thref); % <-- need to carry this to make the template
%refholes = refholes(yrange,xrange); % <-- this is used to manually create the template
%imwrite(refholes,'refholes.png') % <-- write it and open it externally
% get template (this is a label array)
template = imread('holetemplatefull.png');
szref = [size(template,1) size(template,2)];
% find hole centers as linear indices into image
S = regionprops(template,'centroid');
holeidx = round(vertcat(S.Centroid));
holeidx = sub2ind(szref,holeidx(:,2),holeidx(:,1));
% explicitly specify which holes should be filled
% note that i specified 5 and 12 instead of 6 and 11
pluggedholes = [5 12 13 18 19 24 27 29 31 34 35 42 43 45 51 53 56 57 58 61];
% generate logical map of plugs from index list
refplugidx = false(size(holeidx));
refplugidx(pluggedholes) = true;
% %%%% PROCESS WORKING IMAGE %%%%
% get the image, discard color
testimg = imread('rotatedbad2.jpg');
testimg = rgb2gray(testimg);
% detect the plugs
testplug = imfill(imbinarize(testimg),'holes');
testplug = bwareaopen(testplug,100);
% remove the plugs from image
testnoplug = testimg;
testnoplug(testplug) = 0;
% detect holes
holeth = 20;
maxspecklearea = 100;
solidityrange = [0.7 1];
eccentrange = [0 0.95];
testholes = testnoplug <= holeth;
testholes = ~bwareaopen(~testholes,maxspecklearea);
testholes = bwareaopen(testholes,maxspecklearea);
testholes = bwpropfilt(testholes,'solidity',solidityrange);
testholes = bwpropfilt(testholes,'eccentricity',eccentrange);
% calculate convex hull and object rotation
testhull = bwconvhull(testholes);
S = regionprops(testhull,'minferetproperties');
thtest = S(1).MinFeretAngle - 90;
% correct images for rotation
testhull = imrotate(testhull,thtest);
testplug = imrotate(testplug,thtest);
testimg = imrotate(testimg,thtest);
% close-crop plug mask based on extent of convhull
S = regionprops(testhull,'boundingbox');
rect = round(S.BoundingBox);
xrange = rect(1):sum(rect([1 3]));
yrange = rect(2):sum(rect([2 4]));
testplug = testplug(yrange,xrange);
testimg = testimg(yrange,xrange);
% resize moving image to match reference
testplug = imresize(testplug,szref);
testimg = imresize(testimg,szref);
% THIS PART IS DIFFERENT -->
% check hole locations in the working image
% instead of relying on the binary mask (testplug)
% this processes testimg using the blob extents from the template
% this way the plug detection process is independent from the orientation correction
Simg = regionprops(template,testimg,'meanintensity');
observedintensity = vertcat(Simg.MeanIntensity);
% i'm only using the lower threshold where it's necessary due to the low contrast with gray plugs
% at least that retains a bit better robustness for the smaller white plugs
threshold = [125*ones(56,1); 50*ones(6,1)];
testplugidx = observedintensity>threshold;
% <-- THIS PART IS DIFFERENT
% these are linear indices into the template where a plug is missing
plugismissing0 = refplugidx & ~testplugidx; % index into arrays returned by regionprops()
plugismissing = template(holeidx(plugismissing0)); % index into hole template
% these are linear indices into the template where a plug is misplaced
plugismisplaced0 = ~refplugidx & testplugidx; % index into arrays returned by regionprops()
plugismisplaced = template(holeidx(plugismisplaced0)); % index into hole template
% plot the location of missing plugs
imshow(testimg); hold on
[y x] = ind2sub(szref,holeidx(plugismissing0));
plot(x,y,'o','linewidth',3,'markersize',10)
[y x] = ind2sub(szref,holeidx(plugismisplaced0));
plot(x,y,'x','linewidth',3,'markersize',10)
I made a modified test image with plugs in the wrong place. The pluggedholes reference list refers to the plug locations in the original image.
The template label array and the label order have been updated to account for the full 62 holes.
I'm not sure how robust the plug detection will be on the gray plugs if material color or lighting changes much. I picked 50 as the threshold for those locations, but there may be room for adjustment.
Audrius Bieliunas
Audrius Bieliunas 2022년 12월 23일
thank u sir, that was what i look for. U save the day.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Image Analyst
Image Analyst 2022년 11월 13일
There are probably lots of ways to solve this but I'd start like this.
  1. Threshold to find the large two black rectangles on the right side of the jig.
  2. use regionprops to get the two centroids, then find the angle between them
  3. use imrotate to make them level.
  4. then find the spots again and use imtranslate to put the upper right dark rectangle at some known location. Do that for both images.
  5. Then use imabsdiff to subtract the two images.
  6. Threshold to find the difference.
  7. Call imclearborder to get rid of any differences touching the edge of the image.
  8. Call imfill to fill any holes.
  9. Call bwareafilt to get only blobs in a certain known area range.
  10. Call bwlabel or regionprops to count and locate the missing or extra white blob.
As you can see, pretty easy, it's just that there are a lot of simple steps.
Write back if you can't figure it out.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by