Подтвердить что ты не робот

Точка OpenCV (x, y) представляет (столбец, строка) или (строка, столбец)

У меня есть 300 * 200 изображений в матрице src. Я делаю следующую операцию на изображении.

for(int i=0;i<src.rows;i++){
for(int j=0;j<src.cols;j++){
line( src, Point(i,j),Point(i,j), Scalar( 255, 0, 0 ),  1,8 );
}
]
imshow("A",src);
waitKey(0);

Я ожидал, что он будет покрывать все изображение белым цветом, но нижняя часть изображения останется пустой. Если я сделаю это

  for(int i=0;i<src.rows;i++){
    for(int j=0;j<src.cols;j++){
    src.at<uchar>(i,j)=255;
    }
    ]
    imshow("A",src);
    waitKey(0);

Изображение целиком покрыто белым. Таким образом, это означает, что src.at(i, j) использует (i, j) как (строка, столбец), но Point (x, y) использует (x, y) как (столбец, строка)

4b9b3361

Ответ 1

Итак, это означает, что src.at(i, j) использует (i, j) как (строка, столбец), но Point (x, y) использует (x, y) как (столбец, строка)

Это правильно! Поскольку это, похоже, запутывает многих людей, я напишу свое объяснение по этой причине:

В OpenCV cv::Mat используется как для изображений, так и для матриц, поскольку дискретное изображение в основном совпадает с матрицей.

В математике мы имеем несколько разных вещей:

  • которые имеют несколько строк и несколько столбцов.
  • (функции), которые имеют несколько осей и графически представляют график в виде изображения.
  • которые упорядочены по осям системы координат, которая обычно является декартовой координатой.

1. Для матриц математическая нотация заключается в упорядочении в строчном порядке, который

Следуя условной матричной нотации, строки нумеруются первым индексом двумерного массива и столбцов вторым индексом, т.е. a1,2 является вторым элементом первой строки, считая вниз и вправо. (Обратите внимание, что это противоположность декартовых условностей.)

Взято из http://en.wikipedia.org/wiki/Row-major_order#Explanation_and_example

Как и в математике, строка: 0, столбец: 0 - верхний левый элемент матрицы. Строка/столбец точно так же, как в таблицах...

0/0---column--->
 |
 |
row
 |
 |
 v

2. Для Точки выбрана система координат, которая выполняет две вещи: 1. она использует те же размеры единицы и то же самое "происхождение", что и матричная нотация, поэтому верхний левый - это точка (0,0), а длина оси 1 - длина 1 строки или 1 столбец. 2. он использует "обозначение изображения" для осевого упорядочения, что означает, что абсцисса (горизонтальная ось) является первым значением, обозначающим направление x, а ордината (вертикальная ось) является вторым значением, обозначающим направление y.

Точка, где встречаются оси, является общим происхождением двух числовых линий и просто называется началом. Он часто обозначается O, и если так, то оси называются Ox и Oy. Плоскость с определяемыми точками x и y часто упоминается как декартова плоскость или плоскость ху. Значение x называется x-координатой или абсциссой, а значение y называется y-координатой или ординатой.

Выбор букв происходит из исходного соглашения, которое должно использовать последнюю часть алфавита для указания неизвестных значений. Первая часть алфавита использовалась для обозначения известных значений.

http://en.wikipedia.org/wiki/Cartesian_coordinate_system#Two_dimensions

поэтому в идеальном мире мы бы выбрали систему координат точек/изображений:

 ^
 |
 |
 Y
 |
 |
0/0---X--->

но поскольку мы хотим, чтобы это начало в верхнем левом и положительном значениях было снизу, оно:

0/0---X--->
 |
 |
 Y
 |
 |
 v

Таким образом, для обработки изображений люди с первой строкой могут быть странными, но для математиков по оси x будет странно обращаться к матрице.

Итак, в OpenCV вы можете использовать: mat.at<type>(row,column) или mat.at<type>(cv::Point(x,y)) для доступа к одной и той же точке, если x=column и y=row, которая совершенно понятна =)

Надеюсь, это правильно. Я мало знаю о нотациях, но это то, о чем мне говорит мой опыт в математике и визуализации.

Ответ 2

Я нашел быстрое и быстрое решение этой проблемы, просто преобразовывая координаты из opencv в декартовы координаты в 4-м квадранте, просто поместив знак (-) ve перед координатой y.

Таким образом, я смог использовать существующие алгоритмы и все стандартные декартово-системные уравнения с opencv, не затрачивая много накладных расходов на систему, делая дорогостоящее преобразование между системами координат.

0/0---X--->
 |
 |
 Y
 |
 |
 v
 (opencv)

0/0---X----> 
|
|
|
-Y
|
|
v
(4th quadrant)

Ответ 3

Вот наглядный пример, чтобы отличить python [row, columns] от OpenCV [x, y].

import numpy as np
import matplotlib.pyplot as plt
import cv2

img = np.zeros((5,5))  # initialize empty image as numpy array
img[0,2] = 1  # assign 1 to the pixel of row 0 and column 2

M = cv2.moments(img)  # calculate moments of binary image
cX = int(M["m10"] / M["m00"])  # calculate x coordinate of centroid
cY = int(M["m01"] / M["m00"])  # calculate y coordinate of centroid

img2 = np.zeros((5,5))  # initialize another empty image
img2[cX,cY] = 1  # assign 1 to the pixel with x = cX and y = cY

img3 = np.zeros((5,5))  # initialize another empty image
img3[cY,cX] = 1  # inver x and y

plt.figure()
plt.subplots_adjust(wspace=0.4)  # add space between subplots
plt.subplot(131), plt.imshow(img, cmap = "gray"), plt.title("With [rows,cols]")
plt.subplot(132), plt.imshow(img2, cmap = "gray"), plt.title("With [x,y]")
plt.subplot(133), plt.imshow(img3, cmap= "gray"), plt.title("With [y,x]"), plt.xlabel('x'), plt.ylabel('y')

Это выведет:

enter image description here