Проблема с портированием метода RGB2CMYK из С++ в java
Я пытаюсь преобразовать метод из С++ в java. Вот способ:
void rgb2cmyk(cv::Mat& src, std::vector<cv::Mat>& cmyk)
{
CV_Assert(src.type() == CV_8UC3);
cmyk.clear();
for (int i = 0; i < 4; ++i)
cmyk.push_back(cv::Mat(src.size(), CV_32F));
for (int i = 0; i < src.rows; ++i)
{
for (int j = 0; j < src.cols; ++j)
{
cv::Vec3b p = src.at<cv::Vec3b>(i,j);
float r = p[2] / 255.;
float g = p[1] / 255.;
float b = p[0] / 255.;
float k = (1 - std::max(std::max(r,g),b));
cmyk[0].at<float>(i,j) = (1 - r - k) / (1 - k);
cmyk[1].at<float>(i,j) = (1 - g - k) / (1 - k);
cmyk[2].at<float>(i,j) = (1 - b - k) / (1 - k);
cmyk[3].at<float>(i,j) = k;
}
}
}
Проблема связана с методами OpenCv. Вот несколько деталей:
- Я не нашел метод
CV_Assert
в java. не знаю никаких альтернативных
для этого.
-
cmyk.push_back
заменяется на cmyk[i].pushback
- Я использовал
Mat
вместо cv::Vec3b
, он не обнаружил ошибки
-
std::max
заменяется на Math.max
- Проблема заключается в присвоении
cmyk[0].at<float>(i,j)
Есть ли у кого-нибудь предложение или какой-нибудь лучший способ сменить этот метод на java.
Заранее спасибо за помощь....
Edit
Что я сделал
public void rgb2xmyk(Mat src,Mat[] cmyk)
{
//CV_Assert(src.type() == CV_8UC3);
//cmyk.clear();
for (int i = 0; i < 4; ++i)
cmyk[i].push_back(new Mat(src.size(), CvType.CV_32F));
for (int i = 0; i < src.rows; ++i)
{
for (int j = 0; j < src.cols; ++j)
{
double[] p = src.get(i,j);
float r = (float) (p[2] / 255.);
float g = (float) (p[1] / 255.);
float b = (float) (p[0] / 255.);
float k = (1 - Math.max(Math.max(r,g),b));
cmyk[0].at<float>(i,j) = (1 - r - k) / (1 - k);
cmyk[1].at<float>(i,j) = (1 - g - k) / (1 - k);
cmyk[2].at<float>(i,j) = (1 - b - k) / (1 - k);
cmyk[3].at<float>(i,j) = k;
}
}
}
Ответы
Ответ 1
Вы должны убедиться, что массив cmyk Mat имеет размер = 4.
В цикле for я предлагаю вам использовать setTo:
for (int i = 0; i < 4; ++i)
cmyk[i].setTo(new Mat(src.size(), CvType.CV_32F));
во вложенных циклах, где вы заполняете свой cmyk, я бы использовал метод put
cmyk[0].put(i,j,new Float[] {(1 - r - k) / (1 - k)});
cmyk[1].put(i,j,new Float[] {(1 - g - k) / (1 - k)});
cmyk[2].put(i,j,new Float[] {(1 - b - k) / (1 - k)});
cmyk[3].put(i,j,new Float[] {k});
... надеюсь, что это поможет
Ответ 2
Вы можете найти в этой строке:
cmyk[0].at<float>(i,j) = (1 - r - k) / (1 - k);
То, что результат обрабатывается как int перед тем, как его бросать в float, потому что у вас есть целые числа, начинающиеся с каждого блока. Попробуйте:
cmyk[0].at<float>(i,j) = (1.0f - r - k) / (1.0f - k);
Я думаю, что у вас уже есть разумный ответ о том, как обращаться к элементам в этом массиве, хотя (через .put).