ฉันต้องการที่จะหาจุดในภาพที่เป็นจุดศูนย์กลางของการไล่ระดับสีแบบรัศมีเช่นเดียวกับที่แสดงในภาพด้านซ้ายด้านล่าง มีความคิดเห็นเกี่ยวกับวิธีการใช้ Hough transform หรือวิธีการมองเห็นด้วยคอมพิวเตอร์อื่น ๆ อย่างไร
ขอบคุณ
ภาพการค้นหาตัวอย่าง:
ฉันต้องการที่จะหาจุดในภาพที่เป็นจุดศูนย์กลางของการไล่ระดับสีแบบรัศมีเช่นเดียวกับที่แสดงในภาพด้านซ้ายด้านล่าง มีความคิดเห็นเกี่ยวกับวิธีการใช้ Hough transform หรือวิธีการมองเห็นด้วยคอมพิวเตอร์อื่น ๆ อย่างไร
ขอบคุณ
ภาพการค้นหาตัวอย่าง:
คำตอบ:
ฉันทำงานใน opencv และพยายามหาจุดสูงสุดของการไล่ระดับสีที่เกิดจากการแปลงระยะทาง ฉันตระหนักว่าการใช้ morphologic (การกัดเซาะ / การขยาย) ในภาพสีเทามีประโยชน์มากในกรณีนี้ หากคุณลบภาพระดับสีเทาออกไปพิกเซลใด ๆ ก็ตามจะเป็นค่าของเพื่อนบ้านที่ต่ำกว่า / สูงสุด คุณสามารถค้นหาจุดสูงสุดของความเข้มในการไล่ระดับสีโดยการลบภาพระดับสีเทาออกจากภาพที่ขยาย / ถูกกัดเซาะเดียวกัน นี่คือผลลัพธ์ของฉัน:
และวิธีการใน OpenCV / Cpp:
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
int main( int argc, char** argv ){
cv::Mat objects, img ,peaks,BGR;
std::vector<std::vector<cv::Point> > contours;
/* Reads the image*/
BGR=cv::imread(argv[1]);
/* Converts it to Grayscale*/
cv::cvtColor(BGR,img,CV_BGR2GRAY);
/* Devine where are the objects*/
cv::threshold(img,objects,0,255,cv::THRESH_BINARY);
/* In order to find the local maxima, "distance"
* is subtracted from the result of the dilatation of
* "distance". All the peaks keep the save value */
cv::dilate(img,peaks,cv::Mat(),cv::Point(-1,-1),3);
cv::dilate(objects,objects,cv::Mat(),cv::Point(-1,-1),3);
/* Now all the peaks should be exactely 0*/
peaks=peaks-img;
/* And the non-peaks 255*/
cv::threshold(peaks,peaks,0,255,cv::THRESH_BINARY);
peaks.convertTo(peaks,CV_8U);
/* Only the zero values of "peaks" that are non-zero
* in "objects" are the real peaks*/
cv::bitwise_xor(peaks,objects,peaks);
/* The peaks that are distant from less than
* 2 pixels are merged by dilatation */
cv::dilate(peaks,peaks,cv::Mat(),cv::Point(-1,-1),1);
/* In order to map the peaks, findContours() is used.
* The results are stored in "contours" */
cv::findContours(peaks, contours, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
/* just draw them and save the image */
cv::drawContours(BGR,contours,-1,cv::Scalar(255,0,0),-1);
cv::imwrite("result.png",BGR);
return 1;
}
นี่คือสิ่งที่ฉันมีจนถึงตอนนี้ วิธีที่ฉันเติมพื้นที่ Hough ของฉันอยู่ไกลจากที่ดีที่สุด ฉันค่อนข้างแน่ใจว่ามี vectorization บางอย่างที่ฉันสามารถทำได้เพื่อทำให้เร็วขึ้น ฉันใช้ Matlab R2011a รูปภาพต้นฉบับ
ข้อเสนอแนะได้รับการชื่นชมขอบคุณ
clear all; clc; close all;
%% read in image and find gradient information
img = rgb2gray(imread('123.png'));
[rows, columns] = size(img);
[dx, dy] = gradient(double(img));
[x y] = meshgrid(1:columns, 1:rows);
u = dx;
v = dy;
imshow(img);
hold on
quiver(x, y, u, v)
%% create Hough space and populate
hough_space = zeros(size(img));
for i = 1:columns
for j = 1:rows
X1 = i;
Y1 = j;
X2 = round(i + dx(j,i));
Y2 = round(j + dy(j,i));
increment = 1;
slope = (Y2 - Y1) / (X2 - X1);
y_intercept = Y1 - slope * X1;
X3 = X1 + 5;
if X3 < columns && X3 > 1
Y3 = slope * X3 + y_intercept;
if Y3 < rows && Y3 > 1
hough_space = func_Drawline(hough_space, Y1, X1, floor(Y3), floor(X3), increment);
end
end
end
end
imtool(hough_space)
ฉันแก้ไขฟังก์ชั่นการวาดเส้นที่ฉันพบบนศูนย์กลางของ MATLAB เพื่อเพิ่มทีละพิกเซลโดยค่าแทนที่จะตั้งค่าพิกเซลเป็นค่า
function Img = func_DrawLine(Img, X0, Y0, X1, Y1, nG)
% Connect two pixels in an image with the desired graylevel
%
% Command line
% ------------
% result = func_DrawLine(Img, X1, Y1, X2, Y2)
% input: Img : the original image.
% (X1, Y1), (X2, Y2) : points to connect.
% nG : the gray level of the line.
% output: result
%
% Note
% ----
% Img can be anything
% (X1, Y1), (X2, Y2) should be NOT be OUT of the Img
%
% The computation cost of this program is around half as Cubas's [1]
% [1] As for Cubas's code, please refer
% http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=4177
%
% Example
% -------
% result = func_DrawLine(zeros(5, 10), 2, 1, 5, 10, 1)
% result =
% 0 0 0 0 0 0 0 0 0 0
% 1 1 1 0 0 0 0 0 0 0
% 0 0 0 1 1 1 0 0 0 0
% 0 0 0 0 0 0 1 1 1 0
% 0 0 0 0 0 0 0 0 0 1
%
%
% Jing Tian Oct. 31 2000
% scuteejtian@hotmail.com
% This program is written in Oct.2000 during my postgraduate in
% GuangZhou, P. R. China.
% Version 1.0
Img(X0, Y0) = Img(X0, Y0) + nG;
Img(X1, Y1) = Img(X1, Y1) + nG;
if abs(X1 - X0) <= abs(Y1 - Y0)
if Y1 < Y0
k = X1; X1 = X0; X0 = k;
k = Y1; Y1 = Y0; Y0 = k;
end
if (X1 >= X0) & (Y1 >= Y0)
dy = Y1-Y0; dx = X1-X0;
p = 2*dx; n = 2*dy - 2*dx; tn = dy;
while (Y0 < Y1)
if tn >= 0
tn = tn - p;
else
tn = tn + n; X0 = X0 + 1;
end
Y0 = Y0 + 1; Img(X0, Y0) = Img(X0, Y0) + nG;
end
else
dy = Y1 - Y0; dx = X1 - X0;
p = -2*dx; n = 2*dy + 2*dx; tn = dy;
while (Y0 <= Y1)
if tn >= 0
tn = tn - p;
else
tn = tn + n; X0 = X0 - 1;
end
Y0 = Y0 + 1; Img(X0, Y0) = Img(X0, Y0) + nG;
end
end
else if X1 < X0
k = X1; X1 = X0; X0 = k;
k = Y1; Y1 = Y0; Y0 = k;
end
if (X1 >= X0) & (Y1 >= Y0)
dy = Y1 - Y0; dx = X1 - X0;
p = 2*dy; n = 2*dx-2*dy; tn = dx;
while (X0 < X1)
if tn >= 0
tn = tn - p;
else
tn = tn + n; Y0 = Y0 + 1;
end
X0 = X0 + 1; Img(X0, Y0) = Img(X0, Y0) + nG;
end
else
dy = Y1 - Y0; dx = X1 - X0;
p = -2*dy; n = 2*dy + 2*dx; tn = dx;
while (X0 < X1)
if tn >= 0
tn = tn - p;
else
tn = tn + n; Y0 = Y0 - 1;
end
X0 = X0 + 1; Img(X0, Y0) = Img(X0, Y0) + nG;
end
end
end
เรียกใช้ฮิสโตแกรมของการไล่ระดับสีแบบเน้น บนแพทช์ของภาพ - จุดสูงสุดในฮิสโทแกรมแต่ละครั้งจะทำให้คุณมีทิศทางที่โดดเด่นของแพทช์นั้น (เช่นลูกศรที่คุณแสดง)
หาจุดที่ลูกศรทั้งหมดตัดกัน - ถ้าจุดนั้นอยู่ข้างในวัตถุมันอาจเป็นจุดศูนย์กลางของการไล่สีในแนวรัศมี