Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Image processing 当我只看到外边缘时,如何找到圆心?_Image Processing_Matlab - Fatal编程技术网

Image processing 当我只看到外边缘时,如何找到圆心?

Image processing 当我只看到外边缘时,如何找到圆心?,image-processing,matlab,Image Processing,Matlab,使用matlab,我需要通过编程找到圆心,而我只能看到圆的外缘 下面是我正在尝试处理的测试图像: 忽略外边缘周围的黑色。我把相机放在一个望远镜的后面,这就是为什么你只能在中间看到一个小的放大的圆。这些黑圈实际上是一个目标,因此有多个环相互嵌套。 使用imfindcircles()的脚本 在下面的matlab脚本中,我使用了imfindcircles()。imfindcircles()有两个问题。 1.每次调用大约需要2-3秒,这会降低我的应用程序的速度。 2.在上面的示例图像中,它无法预测圆心

使用matlab,我需要通过编程找到圆心,而我只能看到圆的外缘

下面是我正在尝试处理的测试图像:

忽略外边缘周围的黑色。我把相机放在一个望远镜的后面,这就是为什么你只能在中间看到一个小的放大的圆。这些黑圈实际上是一个目标,因此有多个环相互嵌套。

使用imfindcircles()的脚本 在下面的matlab脚本中,我使用了imfindcircles()。imfindcircles()有两个问题。 1.每次调用大约需要2-3秒,这会降低我的应用程序的速度。 2.在上面的示例图像中,它无法预测圆心。它需要先看到更多的圆圈

Rmin = 40; %7 and 12 for small circle
Rmax = 100;

% Create video input object.
vid = videoinput('winvideo',1);

% Set video input object properties for this application.
% Note that example uses both SET method and dot notation method.
set(vid,'TriggerRepeat',100);
vid.FrameGrabInterval = 5;


vid = videoinput('winvideo', 1, 'MJPG_1280x720');
%src = getselectedsource(vid);

%number of frames to get each time the camera is triggered
vid.FramesPerTrigger = 1;

%return grayscale for one less thing to process
vid.ReturnedColorspace = 'grayscale';

%make the trigger type manual. This allows use to grab one frame at a time
triggerconfig(vid, 'manual');

% allow us to capture unlimited frames, with only starting the video once
vid.TriggerRepeat = Inf;

%preview(vid);

%start(vid);

%trigger(vid);

%stoppreview(vid);

% Create a figure window.
%figure;

% Start acquiring frames.
start(vid);

while(true)

    trigger(vid);

    %get a single image frame
    image = getdata(vid);

    %draw the image on screen
    imshow(image);
    drawnow;     % update figure window

    %set the center of the image. This is used as an additional way to
    %calibrate the score, camera, and laser. You can change where the "center" of
    %the camera image is by adjusting these values.
    % [x, y]
    imageCenter = [500, 500];
    viscircles(imageCenter, 5,'EdgeColor','r');

    %find circles (the target) in the image and draw a circle around it
    [centers, radii, metric] = imfindcircles(image,[Rmin Rmax], 'ObjectPolarity', 'dark');

    %make sure a circle on screen was found
    if(centers)
        %draw circle found on screen
        viscircles(centers, radii,'EdgeColor','b');

        %calculate distance from center of the image and the center of the circle
        %x minus x; y minus y; then calc hypotenuse
        circleCenterX = centers(1,1);
        circleCenterY = centers(1,2);

        imageCenterX = imageCenter(1,1);
        imageCenterY = imageCenter(1,2);

        %calculate the di
        distanceX = circleCenterX - imageCenterX;  
        distanceY = circleCenterY - imageCenterY ;

        %calculate the hypotenuse (b^2 + b^2 = c^2)
        hypotenuse = sqrt(distanceX^2 + distanceY^2);

        %create sound based on distance from the center of the image
        a=sin(2*pi*hypotenuse*(0:0.000125:0.05));
        sound(a);

        disp(hypotenuse);

        %if you are withing X pixel of the center make a beeping noise
        if(hypotenuse <= 15)
            a=sin(2*pi*400*(0:0.000125:0.05));
            sound(a);
            sound(a);
            sound(a);
        end

        %show a measuring line to verfiy results
        %h = imdistline;
    end

    %clear memory after each frame to avoid memory leak
    flushdata(vid, 'triggers');

end

%doesnät get run but use these commands to clean up before running the
%script again
imaqreset();
%stop(vid);
%delete(vid);
%clear;
%close(gcf);
Rmin=40;%7和12表示小圆
Rmax=100;
%创建视频输入对象。
vid=视频输入(“winvideo”,1);
%为此应用程序设置视频输入对象属性。
%请注意,该示例同时使用SET方法和点表示法。
设置(视频,'TriggerRepeat',100);
vid.FrameGrabInterval=5;
vid=视频输入(“winvideo”,1,“MJPG_1280x720”);
%src=getselectedsource(vid);
%每次触发相机时要获取的帧数
vid.FramesPerTrigger=1;
%返回要处理的少一件事情的灰度值
vid.ReturnedColorspace=‘灰度’;
%使触发器类型为手动。这允许用户一次抓取一帧
triggerconfig(见“手动”);
%允许我们捕获无限帧,只需启动一次视频
vid.triggerreat=Inf;
%预览(vid);
%启动(vid);
%触发器(vid);
%审查(vid);
%创建一个图形窗口。
%数字;
%开始获取帧。
启动(vid);
while(true)
触发器(vid);
%获取单个图像帧
图像=获取数据(vid);
%在屏幕上绘制图像
imshow(图像);
现在提取;%更新图形窗口
%设置图像的中心。这是用来作为一个额外的方式
%校准分数、摄像机和激光器。您可以更改“中心”的位置
%通过调整这些值,可以创建相机图像。
%[x,y]
图像中心=[500500];
viscircles(图像中心,5,'EdgeColor','r');
%在图像中找到圆(目标),并在其周围画一个圆
[中心,半径,公制]=imfindcircles(图像,[Rmin Rmax],'ObjectPolarity','dark');
%确保在屏幕上找到一个圆圈
国际单项体育联合会(中心)
%绘制屏幕上的圆圈
内圆(中心、半径、“边缘颜色”、“b”);
%计算从图像中心到圆心的距离
%x减去x;y减去y;然后计算斜边
CircleCenter=中心(1,1);
循环中心=中心(1,2);
imageCenterX=imageCenter(1,1);
imageCenterY=imageCenter(1,2);
%计算di
距离X=圆形中心X-图像中心X;
距离Y=循环中心-图像中心;
%计算斜边(b^2+b^2=c^2)
斜边=sqrt(距离X^2+距离Y^2);
%根据与图像中心的距离创建声音
a=sin(2*pi*斜边*(0:0.000125:0.05));
声音(a);
斜边;
%如果使用中心的X像素,则发出嘟嘟声
if(斜边100;%100
%图,imshow(BW);
%http://www.mathworks.de/de/help/images/ref/imdilate.html
%se=应力('线',11,90);
%I2=不扩张(体重,se);
%imshow(BW),标题(“原件”)
%图,imshow(I2),标题(“放大”)
原始体重=体重;
se=链状('圆盘',2);
DBW=imerode(原始BW,se);
%imshow(原始BW)、figure、imshow(原始BW)
%在二值图像中查找区域
区域图像=DBW;
s=区域属性(区域图像,图像,{'Centroid','WeightedCentroid','Area','FilledImage'});
%绘制屏幕上的区域。
如果(drawOnImage==1)
%图,imshow(区域图像);
标题(“加权(红色)和未加权(蓝色)质心位置”);
等等
numObj=numel(s);
对于k=1:numObj
%仅显示大于X像素数的区域
如果(s(k).Area>minPixelArea)
图(s(k).加权质心(1),s(k).加权质心(2),‘r*’;
图(s(k)。质心(1),s(k)。质心(2),‘bo’;
文本(s(k).形心(1),s(k).形心(2),sprintf(“%2.1f”,s(k).形心(1)),“EdgeColor”,“b”,“Color”,“r”);
结束
结束
拖延
结束
shortestDist=100;%存储找到的当前最短距离,默认为something massible,因此很容易被覆盖
shortestDistIndex=0;%存储具有最短距离的点的索引
对于idx=1:numel(s)
%确保当前元素的像素数大于X
%在处理之前
如果(s(idx).Area>minPixelArea)
%获取当前元素的x和y
电流x=s(idx)。质心(1);
电流y=s(idx)。质心(1);
%获取下一个元素的x和y
尝试
nextX=s(idx+1)。质心(1);
nextY=s(idx+1)。质心(1);
抓住
%如果我们在最后一个元素上,try语句将失败,并且
%这将结束for循环
打破
结束
%计算当前质心和下一个质心之间的距离
距离x=nextX-currentX;
距离y=nextY-当前y;
%计算斜边(b^2+b^2=c^2)
斜边=sqrt(距离X^2+距离Y^2);
%如果距离小于当前的“最短距离”,
%覆盖变量

如果(斜边您可以尝试Hough变换来检测圆。

如果圆上有3个点(A、B、C),您可以计算它。外接圆的中心可以在任意两个垂线的交点处找到
function circleCenter = findCircleCenter(image, drawOnImage, toGray)
    %in order to find the center, find the center of all objects in an image.
    %Once we have the centers, we find the shortest distance between these
    %objects. Our image has multiple circle, each inside the other. The center
    %of all these cirlces are the same. By finding the shortest distance
    %between the objects, we can safely assume we found the center of our
    %target when we find two points are very close to each other. 

    %Adjust the number of pixels between the two points of the circle.
    %Explained in details above.
    minCenterPixelDist = 8;
    %the minimum amount of pixels needed in a region to be considered an
    %object for measurement
    minPixelArea = 100;

    if(toGray == 1)
        %convert to grayscale
        image = rgb2gray(image);
        %figure, imshow(image);
    end

    %find the two closest points
    %see if they are less than 8 pixels apart, this is the center

    %threshold the image to make a binary image
    BW = image > 100; %100
    %figure, imshow(BW);

    %http://www.mathworks.de/de/help/images/ref/imdilate.html
    %se = strel('line',11,90);
    %I2 = imdilate(BW,se);
    %imshow(BW), title('Original')
    %figure, imshow(I2), title('Dilated')

    originalBW = BW;  
    se = strel('disk',2);        
    erodedBW = imerode(originalBW,se);
    %imshow(originalBW), figure, imshow(erodedBW)

    %find regions in binary image
    regionImage = erodedBW;
    s = regionprops(regionImage, image, {'Centroid','WeightedCentroid','Area','FilledImage'});

    %draw the regions found on screen.
    if(drawOnImage == 1)
        %figure, imshow(regionImage);
        title('Weighted (red) and Unweighted (blue) Centroid Locations');
        hold on
        numObj = numel(s);
        for k = 1 : numObj

            %only display regions that are bigger than X number of pixels
            if(s(k).Area > minPixelArea)
                plot(s(k).WeightedCentroid(1), s(k).WeightedCentroid(2), 'r*');
                plot(s(k).Centroid(1), s(k).Centroid(2), 'bo');
                text(s(k).Centroid(1),s(k).Centroid(2), sprintf('%2.1f', s(k).Centroid(1)), 'EdgeColor','b','Color','r');
            end
        end
        hold off
    end

    shortestDist = 100; %stores the current shortest distance found, default to somethign massive so it gets overwriten easily
    shortestDistIndex = 0;%stores the index of the point with the shortest distance

    for idx = 1:numel(s)

        %make sure the current element has more than X number of pixels
        %before processing it
        if(s(idx).Area > minPixelArea)
            %get the x and y of the current element
            currentX = s(idx).Centroid(1);
            currentY = s(idx).Centroid(1);

            %get the x and y of the next element
            try
                nextX = s(idx + 1).Centroid(1);
                nextY = s(idx + 1).Centroid(1);
            catch
                %if we are on the last element, the try statement will fail, and
                %this will end the for loop
                break;
            end

            %calculate the distance between the current centroid and the next one
            distanceX = nextX - currentX;  
            distanceY = nextY - currentY;

            %calculate the hypotenuse (b^2 + b^2 = c^2)
            hypotenuse = sqrt(distanceX^2 + distanceY^2);

            %if the distance is less than the current "shortest distance",
            %overwrite the variable
            if(hypotenuse <= shortestDist)
                shortestDist = hypotenuse;
                shortestDistIndex = idx;
            end
        end
    end

    %if the closest points are within a certain number of pixels, we can
    %assume the are the centers of two circles 
    %also make sure the area of this shortest distance is greater than
    %minPixel area
    if(shortestDist < minCenterPixelDist)
         %get the x and y of our shortest distance centroids
         centerOneX = s(shortestDistIndex).Centroid(1);
         centerOneY = s(shortestDistIndex).Centroid(2);

         centerTwoX = s(shortestDistIndex + 1).Centroid(1);
         centerTwoY = s(shortestDistIndex + 1).Centroid(2);

         %calculate the average between the two closest points
         circleCenterX = (centerOneX + centerTwoX)/2;
         circleCenterY = (centerOneY + centerTwoY)/2;

         circleCenter = [circleCenterX, circleCenterY];

         disp(circleCenter);
    else
        circleCenter = [];
    end
end